Русский
Русский
English
Статистика
Реклама

Перевод JavaScript делегирование событий простыми словами



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.

Распространение событий состоит из трех фаз или стадий:

  1. Фаза захвата или погружения начиная с window, document и корневого элемента, событие опускается до целевого элемента (элемента, вызвавшего событие), последовательно проходя через всех его предков
  2. Целевая фаза это когда событие достигает целевого элемента
  3. Фаза поднятия или всплытия (в данном случае, лучше использовать слово всплытие во избежание путаницы с поднятием переменных (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
К списку статей
Опубликовано: 07.09.2020 12:20:38
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Javascript

Программирование

Разработка веб-сайтов

Разработка

Event delegation

Делегирование событий

Event propagation

Распространение событий

Event flow

Поток событий

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru