[JavaScript, Разработка веб-сайтов] Простое объяснение делегирования событий (перевод)
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Приветствую. Представляю вашему вниманию перевод статьи «A Simple Explanation of Event Delegation in JavaScript», опубликованной 14 июля 2020 года автором Dmitri Pavlutin
В данной статье Дмитрий Павлутин объясняет, на чём основан один из базовых паттернов работы с DOM-событиями.
1. Почему делегирование событий?
Давайте напишем скрипт, который при нажатии на HTML-кнопку, будет отправлять сообщение в консоль.
Чтобы срабатывало такое поведение, необходимо в JavaScript найти эту кнопку и с помощью метода addEventListener() прикрепить к ней обработчик события.
<button id="buttonId">Click me</button>
<script>
document.getElementById('buttonId')
.addEventListener('click', () => console.log('Clicked!'));
</script>
Данный способ позволяет начать отслеживать события на одном элементе. Например, на кнопке.
А что, если возникает необходимость отслеживать события на множестве кнопок? Вот пример одного из способов реализаций:
<div id="buttons">
<button class="buttonClass">Click me</button>
<button class="buttonClass">Click me</button>
<!-- Кнопки... -->
<button class="buttonClass">Click me</button>
</div>
<script>
const buttons = document.getElementsByClassName('buttonClass');
for (const button of buttons) {
button.addEventListener('click', () => console.log('Clicked!'));
}
</script>
Посмотреть, как работает данный способ, можно в демонстрации CodeSandbox
Сначала делается выборка всех необходимых кнопок страницы, затем с помощью цикла for (const button of buttons) производится обход всех элементов этого списка, в котором к каждой кнопке прикрепляется обработчик события. Также, когда во время работы с документом на странице появляются новые кнопки, возникает необходимость вручную прикреплять обработчики событий для этих новых элементов.
Существует ли лучший способ?
К счастью, при использовании шаблона "делегирование событий", отслеживание событий на множестве элементов требует наличия только одного обработчика.
Делегирование событий использует особенности работы "распространения событий". Чтобы понять, как работает делегирование, предлагаю сначала разобраться в принципе работы их распространения.
2. Распространение событий
Когда вы нажимаете на кнопку в следующей HTML-разметке:
<html>
<body>
<div id="buttons">
<button class="buttonClass">Click me</button>
</div>
</body>
</html>
На каком количестве элементов сработает событие click? Без сомнений, событие клика получит сама кнопка. Но помимо неё, такое же событие получит и вся цепочка элементов, являющихся её предками (даже объекты document и window).
Событие клика распространяется в 3 этапа:
- Фаза захвата / погружения (capturing phase) – начиная с window, document и корневого элемента, событие погружается сверху вниз по DOM-дереву через предков целевого элемента, на котором произошло событие
- Фаза цели (target phase) – срабатывание соыбытия на элементе, на который пользователь кликнул
- Фаза всплытия (bubble phase) – наконец, событие всплывает по цепочке предков целевого элемента, пока не достигнет корневого элемента, а затем объектов document и window
Третий аргумент captureOrOptions метода addEventListener:
element.addEventListener(eventType, handler[, captureOrOptions]);
позволяет вам перехватывать события на разных этапах их распространения.
- Если аргумент captureOrOptions пропущен, имеет значение false или `{ capture: false }, обработчик будет захватывать события на "Фазе цели" и "Фазе всплытия"
- Если же аргумент captureOrOptions имеет значение true или `{ capture: true }, обработчик сработает уже на "Фазе захвата (погружения)"
В следующем примере обработчик перехватывает событие клика на элементе <body> на "Фазе захвата":
document.body.addEventListener('click', () => {
console.log('Body click event in capture phase');
}, true);
В демонстрации CodeSandbox, при нажатии на кнопку, в консоли можно увидеть, как распространяется событие.
Итак, как распространение события помогает перехватывать события из множества кнопок?
Принцип прост: обработчик события прикрепляется к элементу, являющемуся для кнопок родительским, и при нажатии на кнопку отлавливает всплывающее событие. Именно так работает делегирование событий.
3. Делегирование событий
Давайте воспользуемся делегированием, чтобы отловить клики на несколько кнопок:
<div id="buttons"> <!-- Шаг 1 -->
<button class="buttonClass">Click me</button>
<button class="buttonClass">Click me</button>
<!-- Кнопки... -->
<button class="buttonClass">Click me</button>
</div>
<script>
document.getElementById('buttons')
.addEventListener('click', event => { // Step 2
if (event.target.className === 'buttonClass') { // Step 3
console.log('Click!');
}
});
</script>
Откройте демонстрационный код и кликните на любую кнопку – вы увидите в консоли сообщение "Click!".
Идея делегирования событий роста. Вместо прикрепления обработчиков событий прямо к кнопкам, мы делегируем отслеживание этого события родительскому элементу <div id="buttons">. Когда нажимается кнопка, обработчик, назначенный родительскому элементу ловит всплывающее событие (помните раздел про распространение событий?).
Использование делегирования событий требует 3 шагов:
Шаг 1. Определить общего родителя элементов для отслеживания событий
В примере ниже <div id="buttons"> является общим родителем для кнопок.
Шаг 2. Прикрепить к родительскому элементу обработчик событий
document.getElementById('buttons').addEventListener('click', handler) прикрепляет обработчик событий к родителю кнопок. Этот обработчик также реагирует на нажатия на кнопки, так как события нажатий на кнопки всплывают по всем элементам-предкам (благодаря распространению событий).
Шаг 3. Использовать event.target для выбора целевого элемента
Когда кнопка нажата, функция-обработчик вызывается с аргументом: объектом event. Свойство event.target обращается к элементу, на котором произошло событие (в нашем примере этот элемент – кнопка):
// ...
.addEventListener('click', event => {
if (event.target.className === 'buttonClass') {
console.log('Click!');
}
});
Кстати, на элемент к которому прикреплён сработавший обработчик события, указывает event.currentTarget. В нашем примере event.currentTarget указывает на элемент <div id="buttons">.
Теперь вы можете увидеть преимущества шаблона делегирования событий: вместо прикрепления обработчиков к каждой кнопке, как это было сделано раньше, благодаря делегированию событий, остаётся потребность только в одном обработчике.
4. Резюме
Когда происходит событие нажатия на кнопку (или любое другое распространяющееся событие):
- Сначала событие опускается вниз от window, document, корневого элемента и через всех предков целевого элемента (фаза захвата / погружения)
- Событие происходит на целевом элемента (фаза цели)
- И наконец, событие всплывает вверх через элементы, являющиеся предками, пока не достигнет корневого элемента, document и window (фаза всплытия)
Механизм называется распространением события.
Делегирование событий является полезным шаблоном, так как позволяет отслеживать события на множестве элементов с помощью только одного обработчика.
Для работы делегирования событий нужно 3 шага:
- Определить родителя элементов для отслеживания событий
- Прикрепить на него обработчик событий
- Использовать event.target для выбора целевого элемента
===========
Источник:
habr.com
===========
===========
Автор оригинала: Dmitri Pavlutin
===========Похожие новости:
- [JavaScript, Node.JS, Разработка веб-сайтов] Lock-файлы npm
- [JavaScript] «Светлое» будущее моих фейлов
- [Тестирование IT-систем, JavaScript, Разработка игр] Как пройти финальный уровень JS QA Game от SEMrush
- [GitHub, JavaScript, Игры и игровые приставки, История IT] Разработчик создал из Mac OS 8 приложение для современных ПК на macOS, Windows и Linux
- [JavaScript, ReactJS, Тестирование веб-сервисов] Модульное и интеграционное тестирование в Redux Saga на примерах
- [API, JavaScript, Node.JS, Социальные сети и сообщества] Бот «Умный планировщик»: понимает с полуслова
- [Разработка веб-сайтов, Python, Программирование, Функциональное программирование] Какая асинхронность должна была бы быть в Python
- [CMS, WordPress, Разработка веб-сайтов] Правильное автоматическое заполнение метатегов alt и title изображений для WordPress
- [IT-компании, Лайфхаки для гиков, Разработка веб-сайтов, Разработка мобильных приложений, Управление продуктом] Наука о пользовательском опыте. Использование когнитивных искажений в разработке качественных продуктов
- [JavaScript, Инженерные системы, Транспорт] АСУДД. Разработка всей системы и интерфейса к ней
Теги для поиска: #_javascript, #_razrabotka_vebsajtov (Разработка веб-сайтов), #_javascript, #_web_development, #_frontend, #_razrabotka_vebsajtov (разработка веб-сайтов), #_javascript, #_razrabotka_vebsajtov (
Разработка веб-сайтов
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 18:27
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Приветствую. Представляю вашему вниманию перевод статьи «A Simple Explanation of Event Delegation in JavaScript», опубликованной 14 июля 2020 года автором Dmitri Pavlutin В данной статье Дмитрий Павлутин объясняет, на чём основан один из базовых паттернов работы с DOM-событиями. 1. Почему делегирование событий? Давайте напишем скрипт, который при нажатии на HTML-кнопку, будет отправлять сообщение в консоль. Чтобы срабатывало такое поведение, необходимо в JavaScript найти эту кнопку и с помощью метода addEventListener() прикрепить к ней обработчик события. <button id="buttonId">Click me</button>
<script> document.getElementById('buttonId') .addEventListener('click', () => console.log('Clicked!')); </script> Данный способ позволяет начать отслеживать события на одном элементе. Например, на кнопке. А что, если возникает необходимость отслеживать события на множестве кнопок? Вот пример одного из способов реализаций: <div id="buttons">
<button class="buttonClass">Click me</button> <button class="buttonClass">Click me</button> <!-- Кнопки... --> <button class="buttonClass">Click me</button> </div> <script> const buttons = document.getElementsByClassName('buttonClass'); for (const button of buttons) { button.addEventListener('click', () => console.log('Clicked!')); } </script> Посмотреть, как работает данный способ, можно в демонстрации CodeSandbox Сначала делается выборка всех необходимых кнопок страницы, затем с помощью цикла for (const button of buttons) производится обход всех элементов этого списка, в котором к каждой кнопке прикрепляется обработчик события. Также, когда во время работы с документом на странице появляются новые кнопки, возникает необходимость вручную прикреплять обработчики событий для этих новых элементов. Существует ли лучший способ? К счастью, при использовании шаблона "делегирование событий", отслеживание событий на множестве элементов требует наличия только одного обработчика. Делегирование событий использует особенности работы "распространения событий". Чтобы понять, как работает делегирование, предлагаю сначала разобраться в принципе работы их распространения. 2. Распространение событий Когда вы нажимаете на кнопку в следующей HTML-разметке: <html>
<body> <div id="buttons"> <button class="buttonClass">Click me</button> </div> </body> </html> На каком количестве элементов сработает событие click? Без сомнений, событие клика получит сама кнопка. Но помимо неё, такое же событие получит и вся цепочка элементов, являющихся её предками (даже объекты document и window). Событие клика распространяется в 3 этапа:
Третий аргумент captureOrOptions метода addEventListener: element.addEventListener(eventType, handler[, captureOrOptions]);
позволяет вам перехватывать события на разных этапах их распространения.
В следующем примере обработчик перехватывает событие клика на элементе <body> на "Фазе захвата": document.body.addEventListener('click', () => {
console.log('Body click event in capture phase'); }, true); В демонстрации CodeSandbox, при нажатии на кнопку, в консоли можно увидеть, как распространяется событие. Итак, как распространение события помогает перехватывать события из множества кнопок? Принцип прост: обработчик события прикрепляется к элементу, являющемуся для кнопок родительским, и при нажатии на кнопку отлавливает всплывающее событие. Именно так работает делегирование событий. 3. Делегирование событий Давайте воспользуемся делегированием, чтобы отловить клики на несколько кнопок: <div id="buttons"> <!-- Шаг 1 -->
<button class="buttonClass">Click me</button> <button class="buttonClass">Click me</button> <!-- Кнопки... --> <button class="buttonClass">Click me</button> </div> <script> document.getElementById('buttons') .addEventListener('click', event => { // Step 2 if (event.target.className === 'buttonClass') { // Step 3 console.log('Click!'); } }); </script> Откройте демонстрационный код и кликните на любую кнопку – вы увидите в консоли сообщение "Click!". Идея делегирования событий роста. Вместо прикрепления обработчиков событий прямо к кнопкам, мы делегируем отслеживание этого события родительскому элементу <div id="buttons">. Когда нажимается кнопка, обработчик, назначенный родительскому элементу ловит всплывающее событие (помните раздел про распространение событий?). Использование делегирования событий требует 3 шагов: Шаг 1. Определить общего родителя элементов для отслеживания событий В примере ниже <div id="buttons"> является общим родителем для кнопок. Шаг 2. Прикрепить к родительскому элементу обработчик событий document.getElementById('buttons').addEventListener('click', handler) прикрепляет обработчик событий к родителю кнопок. Этот обработчик также реагирует на нажатия на кнопки, так как события нажатий на кнопки всплывают по всем элементам-предкам (благодаря распространению событий). Шаг 3. Использовать event.target для выбора целевого элемента Когда кнопка нажата, функция-обработчик вызывается с аргументом: объектом event. Свойство event.target обращается к элементу, на котором произошло событие (в нашем примере этот элемент – кнопка): // ...
.addEventListener('click', event => { if (event.target.className === 'buttonClass') { console.log('Click!'); } }); Кстати, на элемент к которому прикреплён сработавший обработчик события, указывает event.currentTarget. В нашем примере event.currentTarget указывает на элемент <div id="buttons">. Теперь вы можете увидеть преимущества шаблона делегирования событий: вместо прикрепления обработчиков к каждой кнопке, как это было сделано раньше, благодаря делегированию событий, остаётся потребность только в одном обработчике. 4. Резюме Когда происходит событие нажатия на кнопку (или любое другое распространяющееся событие):
Механизм называется распространением события. Делегирование событий является полезным шаблоном, так как позволяет отслеживать события на множестве элементов с помощью только одного обработчика. Для работы делегирования событий нужно 3 шага:
=========== Источник: habr.com =========== =========== Автор оригинала: Dmitri Pavlutin ===========Похожие новости:
Разработка веб-сайтов ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 18:27
Часовой пояс: UTC + 5