JavaScript – Всплытие и погружение событий


JavaScript – Всплытие и погружение событий

JavaScript - Всплытие и погружение событий

Когда некоторый объект инициирует событие, то оно не просто возникает на нём, а распространяется в документе определённым образом.

Это распространение является двунаправленным: от window к целевому элементу и обратно.

Согласно стандарту, оно делится на 3 фазы:

  1. Фаза погружения или захвата – от window к родителю цели (цель – это объект, который инициировал это событие).
  2. Фаза цели – событие на цели.
  3. Фаза всплытия – обратно, от родителя цели к window .

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

Фаза погружения события

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

Этот аргумент задаёт фазу, на которой нужно отлавливать событие.

По умолчанию аргумент capture имеет значение false . Если его не указать или установить равным false , то обработчик в этом случае будет работать на этапе всплытия.

Например, в следующем примере фаза погружения при клике на будет представлять вот такую цепочку: window → document → html → body → article → section .

Фаза погружения события

Пример, в котором обработаем событие click на фазе погружения:

Добавление обработчика на фазе погружения события

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

В обработчике получить элемент для которого вызван обработчик можно не только с помощью currentTarget , но и посредством ключевого слова this .

Фаза цели

На этой фазе будут вызваны все обработчики, прикреплённые к целевому объекту, независимо от того каким способом они назначены.

В примере который рассмотрели выше фаза цели при клике на это конечно сам элемент: img .

Фаза цели

Добавление обработчика посредством HTML-атрибута onclick :

Добавление обработчика к элементу

Добавление обработчика посредством свойства onclick :

Добавление обработчика через addEventListener :

Фаза всплытия

На фазы всплытия будут вызываться обработчики, которые мы зарегистрировали через HTML-атрибут on{event} , свойство on{event} и addEventListener (с capture равным false или без его указания).

В примере приведённом выше фаза всплытия при клике на будет распространяться вот так: section → article → body → html → document → window .

Фаза всплытия события

Пример, в котором обработаем событие click на фазе всплытия:

Добавление обработчика к элементу на фазе всплытия

Пример, показывающий весь цикл путешествия события

Рассмотрим следующий пример:

При клике на элементе #level3 событие click начнёт путешествовать от window вниз по цепочке родителей до этого целевого элемента. Как только оно его достигнет, оно пойдёт вверх по цепочке родителей обратно до window .

Т.е. при клике по #level3 :

  1. Фаза погружения : window → document → html → body → #level-1 → #level-2
  2. Фаза цели : #level-3
  3. Фаза всплытия : #level-2 → #level-1 → body → html → document → window

Чтобы программно посмотреть, как это происходит добавим обработчики ко всем участвующих в этом процессе элементам, а также к объектам document и window :

Распространение события в браузере

На скриншоте самый маленький по размеру квадрат – div#level-3 , тот который побольше – div#level-2 , а самый большой – div#level-1 .

Обработчики на цели срабатывают как те, которые установлены на погружение, так и на всплытие. Поэтому у нас это сообщение «#level-3» вывелось 2 раза.

Получение номера фазы осуществляется с помощью свойства eventPhase (1 – погружение, 2 – цель, 3 – всплытие).

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

Делегирование событий – это механизм реагирования на событие через одного общего для этих элементов родителя.

Как это работает?

Делегирование возможно благодаря тому, что события всплывают. А это означает, что оно возникает не только на самом элементе, но затем на его родителе, потом на родителе его родителя и так далее вверх по цепочке до window .

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

Зачем это нужно?

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

Допустим, есть список:

Предположим, что при нажатии на каждый элемент списка должно что-то произойти. Например, выводиться сообщение.

    , то как вы узнаете, какой элемент был нажат?

Всё просто. Для этого предназначено свойство объекта события target . Оно содержит ссылку на элемент, на который фактически нажали.

Ещё один пример, в котором добавим возможность переключать видимость вложенных списков при клике на элемент . Чтобы не привязывать событие конкретно к элементу выполним этого посредством делегирования, т.е. назначим обработчик элементу ul.list :

JavaScript - Делегирование событий (пример)

Прерывания всплытия или погружения события

Всплытие или погружение события можно прервать. Осуществляется это посредством вызова метода объекта события stopPropagation в обработчике.

Бесспорно, всплытие — это очень удобно и архитектурно прозрачно. Не прекращайте его без явной нужды.

Например, прервём всплытие события click на элементе body :

Теперь, если кликнуть на элементе #level-3 , событие начнёт всплывать. Когда оно дойдёт до body , вызов метода stopPropagation остановит дальнейшее всплытие события click . Таким образом событие click не возникнет на элементе html , и следовательно обработчик, который мы добавили вызван не будет.

JavaScript - Прерывание всплытия события click

Теперь, если закомментировать строчку, где вызываем stopPropagation , то увидим, что прерывания всплытия события не произойдёт.

JavaScript - Без прерывания всплытия события click

Задачи

Вывести в контент кнопки количество кликов по ней

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

JavaScript - Вывести в контент кнопки количество кликов по ней

Исходный код динамически добавляющий кнопки на страницу:

При нажатию на кнопку перейти в начало страницы

Перед каждым заголовком h2 кроме первого динамически добавлена кнопка с классом top .

JavaScript - При нажатию на кнопку перейти в начало страницы

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


Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *