[JavaScript, Программирование, Разработка веб-сайтов] JavaScript: делегирование событий простыми словами (перевод)
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
1. Почему делегирование событий (event delegation)?
Реализуем вывод сообщения в консоль по нажатию кнопки.
Для этого нужно найти кнопку на странице и добавить ей обработчик события click с помощью метода addEventListener:
<button>Нажми на меня нежно</button>
document.querySelector('button')
.addEventListener('click', () => console.log('Клик!'))
Данный способ используется для обработки («прослушивания») событий на одном элементе, в нашем случае, на кнопке.
Но что если у нас имеется несколько кнопок?
Вот возможная реализация:
<div>
<button>Нажми на меня нежно</button>
<button>Нажми на меня нежно</button>
<button>Нажми на меня нежно</button>
<!-- другие кнопки -->
</div>
document.querySelectorAll('button')
.forEach(button => button.addEventListener('click', () => console.log('Клик!')))
Кнопки перебираются с помощью метода forEach и на каждую «вешается» обработчик («слушатель»). При таком подходе при добавлении или удалении кнопок придется вручную добавлять/удалять соответствующие обработчики.
Существует ли другой способ это сделать?
К счастью, при использовании делегирования событий мы можем ограничиться одним обработчиком.
При делегировании событий используются особенности механизма распространения или потока событий (event propagation/flow). Поэтому для понимания работы делегирования, сначала разберемся с тем, что такое распространение событий.
2. Распространение событий
При клике по кнопке в следующей разметке:
<html>
<body>
<div class="buttons">
<button>Нажми на меня нежно</button>
</div>
</body>
</html>
Сколько элементов зарегистрирует событие click? Без сомнения, сама кнопка. Но также… все предки (родительские элементы) кнопки, включая объекты document и window.
Распространение событий состоит из трех фаз или стадий:
- Фаза захвата или погружения — начиная с window, document и корневого элемента, событие опускается до целевого элемента (элемента, вызвавшего событие), последовательно проходя через всех его предков
- Целевая фаза — это когда событие достигает целевого элемента
- Фаза поднятия или всплытия (в данном случае, лучше использовать слово «всплытие» во избежание путаницы с поднятием переменных (hoisting)) — событие поднимается от целевого элемента через всех его предков до document и window
Метод addEventListener принимает третий необязательный аргумент — captureOrOptions:
element.addEventListener(eventType, handler[, captureOrOptions])
Двумя первыми аргументами являются тип события и функция обратного вызова — колбэк, предназначенный для обработки события.
Третий аргумент позволяет перехватывать событие на определенной фазе его распространения:
- Если аргумент captureOrOptions отсутствует либо его значением является false или {capture: false}, тогда событие перехватывается на целевой стадии и стадии всплытия
- Если значением этого аргумента является true или {capture: true}, тогда событие перехватывается на стадии погружения
«Перехватывается» означает, что возникновение события регистрируется только на указанных фазах распространения.
В следующем примере мы регистрируем обработчик события click на элементе body на фазе захвата:
document.body.addEventListener('click', () => {
console.log('Аз есмь обработка cобытия клик элемента body на стадии погружения')
}, true)
Хорошо, но как распространение событий может помочь с кнопками?
Алгоритм простой: регистрируем обработчик на родительском элементе и перехватываем события на фазе всплытия. В этом суть делегирования событий.
3. Делегирование событий
Перепишем наш код, используя полученные знания:
<div>
<button>Нажми на меня нежно</button>
<button>Нажми на меня нежно</button>
<button>Нажми на меня нежно</button>
<!-- другие кнопки -->
</div>
document.querySelector('div')
.addEventListener('click', event => {
// проверяем, что событие возникло на кнопке,
// используя свойство tagName - название тега заглавными буквами
// event.target - цель события, целевой элемент
if (event.target.tagName === 'BUTTON') {
console.log('Клик!')
}
})
В основе делегирования событий лежит простая идея. Вместо регистрации обработчиков на каждой кнопке, мы делегируем обработку событий родительскому элементу кнопок. При нажатии кнопки родительский элемент перехватывает всплывающее событие.
Таким образом, делегирование событий состоит из трех этапов:
Определение родителя целевых элементов
В приведенном примере таким родителем является контейнер div.
Добавление обработчика к родительскому элементу
document.querySelector('div').addEventListener('click', handler) регистрирует обработчик на контейнере для кнопок. Обработчик срабатывает при достижении контейнера события click, поднимающегося от целевого элемента.
event.target используется для определения кнопки, по которой кликнули
При нажатии кнопки вызывается колбэк, которому в качестве аргумента передается объект event — событие. Свойство данного объекта target содержит ссылку на элемент, вызвавший события, т.е. кнопку, по которой кликнули.
К слову, event.currentTarget указывает на элемент, на котором зарегистрирован обработчик, в нашем случае, контейнер для кнопок.
Теперь вы должны понимать, в чем заключается преимущество использования делегирования событий: вместо добавления обработчиков ко всем дочерним элементам, мы добавляем его только к родительскому элементу. Это избавляет нас от необходимости редактирования обработчиков при добавлении/удалении элементов.
Заключение
Когда возникает событие click (или любое другое событие, которое распространяется):
- Данное событие спускается от window и document до целевого элемента через всех его предков (фаза погружения или захвата)
- Событие достигает целевого элемента (целевая фаза)
- Наконец, событие всплывает от целевого элемента через его предков до document и window
Этот механизм назвается распространением событий.
Данный механизм может использоваться для обработки событий, вызываемых несколькими элементами, посредством регистрации всего лишь одного обработчика.
Для реализации делегирования событий нужно выполнить следующее:
- Определить родителя элементов, вызывающих событие
- Зарегистрировать на нем обработчик
- Использовать event.target для определения целевого элемента
Надеюсь, статья была вам полезной. Благодарю за внимание.
===========
Источник:
habr.com
===========
===========
Автор оригинала: Dmitri Pavlutin
===========Похожие новости:
- [Разработка веб-сайтов, JavaScript, Программирование, Отладка] Обработка ошибок в JavaScript
- [Информационная безопасность, Разработка веб-сайтов] Как Web Bundles навредят блокировщикам контента, инструментам для безопасности и открытому вебу (перевод)
- [Интерфейсы, Компьютерное железо, Производство и разработка электроники] USB4: все тот же USB?
- [Производство и разработка электроники, Дизайн, Электроника для начинающих] Как мы подсчитали, сколько на самом деле может стоить разработка корпуса
- [Программирование, C++] std::atomic. Модель памяти C++ в примерах
- [JavaScript, TypeScript] SEO npm-пакета: почему важно правильно настраивать конфиг и писать тесты
- [1С-Битрикс, MySQL, Информационная безопасность, Разработка веб-сайтов, Управление проектами] Интернет-магазин как черная дыра в бюджете
- [Читальный зал, Карьера в IT-индустрии, Фриланс] Как найти клиентов? (Фриланс, консалтинг) (перевод)
- [JavaScript, Браузеры, Разработка веб-сайтов] Про Shadow DOM
- [Программирование, Управление персоналом] Вредные советы: как заставить программиста работать лучше
Теги для поиска: #_javascript, #_programmirovanie (Программирование), #_razrabotka_vebsajtov (Разработка веб-сайтов), #_javascript, #_programmirovanie (программирование), #_razrabotka (разработка), #_event_delegation, #_delegirovanie_sobytij (делегирование событий), #_event_propagation, #_rasprostranenie_sobytij (распространение событий), #_event_flow, #_potok_sobytij (поток событий), #_javascript, #_programmirovanie (
Программирование
), #_razrabotka_vebsajtov (
Разработка веб-сайтов
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 17:21
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
1. Почему делегирование событий (event delegation)? Реализуем вывод сообщения в консоль по нажатию кнопки. Для этого нужно найти кнопку на странице и добавить ей обработчик события click с помощью метода addEventListener: <button>Нажми на меня нежно</button>
document.querySelector('button') .addEventListener('click', () => console.log('Клик!')) Данный способ используется для обработки («прослушивания») событий на одном элементе, в нашем случае, на кнопке. Но что если у нас имеется несколько кнопок? Вот возможная реализация: <div>
<button>Нажми на меня нежно</button> <button>Нажми на меня нежно</button> <button>Нажми на меня нежно</button> <!-- другие кнопки --> </div> document.querySelectorAll('button') .forEach(button => button.addEventListener('click', () => console.log('Клик!'))) Кнопки перебираются с помощью метода forEach и на каждую «вешается» обработчик («слушатель»). При таком подходе при добавлении или удалении кнопок придется вручную добавлять/удалять соответствующие обработчики. Существует ли другой способ это сделать? К счастью, при использовании делегирования событий мы можем ограничиться одним обработчиком. При делегировании событий используются особенности механизма распространения или потока событий (event propagation/flow). Поэтому для понимания работы делегирования, сначала разберемся с тем, что такое распространение событий. 2. Распространение событий При клике по кнопке в следующей разметке: <html>
<body> <div class="buttons"> <button>Нажми на меня нежно</button> </div> </body> </html> Сколько элементов зарегистрирует событие click? Без сомнения, сама кнопка. Но также… все предки (родительские элементы) кнопки, включая объекты document и window. Распространение событий состоит из трех фаз или стадий:
Метод addEventListener принимает третий необязательный аргумент — captureOrOptions: element.addEventListener(eventType, handler[, captureOrOptions])
Двумя первыми аргументами являются тип события и функция обратного вызова — колбэк, предназначенный для обработки события. Третий аргумент позволяет перехватывать событие на определенной фазе его распространения:
«Перехватывается» означает, что возникновение события регистрируется только на указанных фазах распространения. В следующем примере мы регистрируем обработчик события click на элементе body на фазе захвата: document.body.addEventListener('click', () => {
console.log('Аз есмь обработка cобытия клик элемента body на стадии погружения') }, true) Хорошо, но как распространение событий может помочь с кнопками? Алгоритм простой: регистрируем обработчик на родительском элементе и перехватываем события на фазе всплытия. В этом суть делегирования событий. 3. Делегирование событий Перепишем наш код, используя полученные знания: <div>
<button>Нажми на меня нежно</button> <button>Нажми на меня нежно</button> <button>Нажми на меня нежно</button> <!-- другие кнопки --> </div> document.querySelector('div') .addEventListener('click', event => { // проверяем, что событие возникло на кнопке, // используя свойство tagName - название тега заглавными буквами // event.target - цель события, целевой элемент if (event.target.tagName === 'BUTTON') { console.log('Клик!') } }) В основе делегирования событий лежит простая идея. Вместо регистрации обработчиков на каждой кнопке, мы делегируем обработку событий родительскому элементу кнопок. При нажатии кнопки родительский элемент перехватывает всплывающее событие. Таким образом, делегирование событий состоит из трех этапов: Определение родителя целевых элементов В приведенном примере таким родителем является контейнер div. Добавление обработчика к родительскому элементу document.querySelector('div').addEventListener('click', handler) регистрирует обработчик на контейнере для кнопок. Обработчик срабатывает при достижении контейнера события click, поднимающегося от целевого элемента. event.target используется для определения кнопки, по которой кликнули При нажатии кнопки вызывается колбэк, которому в качестве аргумента передается объект event — событие. Свойство данного объекта target содержит ссылку на элемент, вызвавший события, т.е. кнопку, по которой кликнули. К слову, event.currentTarget указывает на элемент, на котором зарегистрирован обработчик, в нашем случае, контейнер для кнопок. Теперь вы должны понимать, в чем заключается преимущество использования делегирования событий: вместо добавления обработчиков ко всем дочерним элементам, мы добавляем его только к родительскому элементу. Это избавляет нас от необходимости редактирования обработчиков при добавлении/удалении элементов. Заключение Когда возникает событие click (или любое другое событие, которое распространяется):
Этот механизм назвается распространением событий. Данный механизм может использоваться для обработки событий, вызываемых несколькими элементами, посредством регистрации всего лишь одного обработчика. Для реализации делегирования событий нужно выполнить следующее:
Надеюсь, статья была вам полезной. Благодарю за внимание. =========== Источник: habr.com =========== =========== Автор оригинала: Dmitri Pavlutin ===========Похожие новости:
Программирование ), #_razrabotka_vebsajtov ( Разработка веб-сайтов ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 17:21
Часовой пояс: UTC + 5