http://wm-monitoring.ru/ ')) {alert('Спасибо за то что установили нашу кнопку! =)');} else {alert('Очень жаль! =(');}"> http://wm-monitoring.ru/

Event Bubbling в JavaScript? Распространение событий объяснено

  1. Что такое распространение событий?
  2. Этап захвата событий
  3. Целевая фаза события
  4. Фаза событий
  5. Применяя это на практике
  6. Остановка распространения
  7. Остановка немедленного распространения
  8. Отмена мероприятия
  9. Заключение
  10. Рекомендации

Пузырьки событий - это термин, который вы могли встретить в своих путешествиях по JavaScript. Это относится к порядку, в котором вызываются обработчики событий, когда один элемент вложен во второй элемент, и оба элемента зарегистрировали прослушиватель для одного и того же события (например, щелчок).

Но всплески событий - это только одна часть головоломки. Это часто упоминается в связи с захватом и распространением событий. А для работы с событиями в JavaScript необходимо четкое понимание всех трех концепций, например, если вы хотите реализовать шаблон делегирования события ,

В этом посте я объясню каждый из этих терминов и продемонстрирую, как они сочетаются друг с другом. Я также покажу вам, как базовое понимание потока событий JavaScript может дать вам детальный контроль над вашим приложением. Обратите внимание, что это не учебник по событиям, поэтому предполагается знакомство с темой. Если вы хотите узнать больше о событиях в целом, почему бы не проверить нашу книгу: JavaScript: от новичка до ниндзя ,

Что такое распространение событий?

Начнем с распространения событий. Это общий термин как для всплытия событий, так и для захвата событий. Рассмотрим типичную разметку для создания списка связанных изображений, например, для галереи миниатюр:

<ul> <li> <a href="..."> <img src = "..." alt = ""> </a> <li> <a href="..."> <img src = "..." alt = ""> </a> ... <li> <a href="..."> <img src = "..." alt = ""> </a> < / UL>

Щелчок по изображению генерирует не только событие щелчка для соответствующего элемента IMG, но также и для родительского элемента A, для дедушки LI и т. Д., Проходя весь путь до всех предков элемента, прежде чем завершиться в объекте окна. ,

В терминологии DOM изображение является целью события , самым внутренним элементом, над которым произошел щелчок. Цель события и его предки от родительского объекта до оконного объекта образуют ветвь в дереве DOM. Например, в галерее изображений эта ветвь будет состоять из узлов: IMG, A, LI, UL, BODY, HTML, document, window.

Обратите внимание, что окно на самом деле не является узлом DOM, но оно реализует интерфейс EventTarget, поэтому для простоты мы обрабатываем его, как если бы он был родительским узлом объекта документа.

Эта ветвь важна, потому что это путь, по которому события распространяются (или проходят). Это распространение - это процесс вызова всех слушателей для данного типа события, привязанных к узлам в ветви. Каждый слушатель будет вызываться с объектом события, который собирает информацию, относящуюся к событию (подробнее об этом позже).

Помните, что несколько слушателей могут быть зарегистрированы на узле для одного и того же типа события. Когда распространение достигает одного такого узла, слушатели вызываются в порядке их регистрации.

Следует также отметить, что определение ветвления является статическим, то есть оно устанавливается при первоначальной отправке события. Изменения дерева, происходящие во время обработки события, будут игнорироваться.

Распространение является двунаправленным, от окна до цели события и обратно. Это распространение можно разделить на три этапа:

  1. Из окна к целевому родителю события: это фаза захвата
  2. Сама цель события: это целевая фаза
  3. От родителя цели события обратно к окну: пузырьковая фаза

Что отличает эти фазы, так это тип слушателей, которые называются.

Этап захвата событий

На этом этапе вызываются только прослушиватели захвата , а именно те прослушиватели, которые были зарегистрированы с использованием значения true для третьего параметра addEventListener :

el.addEventListener ('click', listener, true)

Если этот параметр пропущен, его значение по умолчанию равно false, и слушатель не является перехватчиком.

Таким образом, на этом этапе вызываются только средства захвата, найденные на пути от окна к целевому родителю события.

Целевая фаза события

На этом этапе будут вызываться все слушатели, зарегистрированные на цели события, независимо от значения их флага захвата.

Фаза событий

Во время фазы всплытия событий будут вызываться только те, кто не захватывает. То есть только слушатели, зарегистрированные со значением false для третьего параметра addEventListener ():

el.addEventListener ('click', listener, false) // слушатель не захватывает el.addEventListener ('click', listener) // слушатель не захватывает

Обратите внимание, что пока все события перетекают к цели события с фазой захвата, фокусом, размытием, загрузкой и некоторыми другими, не всплывают. То есть их путешествие останавливается после целевой фазы.

Следовательно, в конце распространения каждый слушатель на ветви был вызван ровно один раз.

Пузырьки событий происходят не для всех видов событий. Во время распространения слушатель может узнать, всплыло ли событие, прочитав логическое свойство .bubbles объекта события.

Три этапа потока событий показаны на следующей диаграмме из W3C UIEvents спецификация ,

Три этапа потока событий показаны на следующей диаграмме из   W3C UIEvents спецификация   ,

Copyright © 2016 World Wide Web Consortium, (MIT, ERCIM, Keio, Beihang) ,

Я уже упоминал свойство .bubbles объекта события. Этот объект предоставляет ряд других свойств, которые доступны слушателям для доступа к информации о распространении.

  • e.target ссылается на цель события.
  • e.currentTarget это узел, на котором был запущен прослушиватель. Это то же значение контекста вызова слушателя, то есть значение, на которое ссылается ключевое слово this.
  • Мы можем даже узнать текущую фазу с e.eventPhase , Это целое число, которое ссылается на одну из трех констант конструктора событий CAPTURING_PHASE, BUBBLING_PHASE и AT_TARGET.

Применяя это на практике

Давайте рассмотрим вышеизложенные концепции на практике. На следующем рисунке пять вложенных квадратных ячеек с именем b0… b4. Первоначально видна только внешняя коробка b0; внутренние отобразятся, когда на них наведет указатель мыши. Когда мы нажимаем на поле, журнал потока распространения отображается в таблице справа.

Увидеть перо jmXdpz по SitePoint ( @SitePoint ) на CodePen ,

Можно даже щелкнуть за пределами блоков: в этом случае целью события будет элемент BODY или HTML, в зависимости от местоположения экрана щелчка.

Остановка распространения

Распространение события может быть остановлено любым слушателем, вызвав stopPropagation метод объекта события. Это означает, что не будут вызваны все слушатели, зарегистрированные на узлах на пути распространения, которые следуют за текущей целью. Вместо этого все остальные оставшиеся слушатели, прикрепленные к текущей цели, все равно получат событие.

Мы можем проверить это поведение с простой форк предыдущего демо просто вставив вызов stopPropagation () в один из слушателей. Здесь мы добавили нового слушателя в качестве средства захвата к списку обратных вызовов, зарегистрированных в окне:

window.addEventListener ('click', e => {e.stopPropagation ();}, true); window.addEventListener ('click', listener ('c1'), true); window.addEventListener ('click', listener ('c2'), true); window.addEventListener ('click', listener ('b1')); window.addEventListener ('click', listener ('b2'));

Таким образом, при любом щелчке по полю распространение останавливается рано, достигая только слушателей захвата в окне.

Остановка немедленного распространения

Как указано в его названии, stopImmediatePropagation сразу же тормозит, не давая даже братьям и сестрам текущего слушателя получить событие. Мы можем увидеть это с минимальное изменение последней ручки :

window.addEventListener ('click', e => {e.stopImmediatePropagation ();}, true); window.addEventListener ('click', listener ('c1'), true); window.addEventListener ('click', listener ('c2'), true); window.addEventListener ('click', listener ('b1')); window.addEventListener ('click', listener ('b2'));

Теперь ничего не выводится в таблицу журнала, ни строки захвата окна c1 и c2, потому что распространение останавливается после выполнения нового слушателя.

Отмена мероприятия

Некоторые события связаны с действием по умолчанию, которое браузер выполняет в конце распространения. Например, нажатие на элемент ссылки или нажатие на кнопку отправки формы заставляет браузер перейти на новую страницу или отправить форму соответственно.

Можно избежать выполнения таких действий по умолчанию с отменой события, вызвав еще один метод объекта события, e.preventDefault в слушателе.

Заключение

В связи с этим я надеюсь показать вам, как происходит всплытие и захват событий в JavaScript. Если у вас есть какие-либо вопросы или комментарии, я был бы рад услышать их в обсуждении ниже.

Рекомендации

Эта статья была рецензирована Яфи Берхану а также Доминик Майерс , Спасибо всем рецензентам SitePoint за то, что сделали контент SitePoint как можно лучше!

Карта