Прохождение события
- Событие (DOM Event) всегда начинается от корня документа.
- Из корня событие проходит по дереву DOM и останавливается на элементе, который вызвал событие
<td>
, это – цель события (event target). - Событие проходит по кратчайшему пути, но по мере прохождения уведомляется каждый элемент, который встретится на этом пути. Если у такого элемента есть обработчик для этого события, он будет вызван.
- Когда событие достигает своей цели
<td>
, оно не останавливается. - Событие продолжается, оно возвращается назад к корню.
- Каждый элемент на пути события, по мере возвращения, получает уведомление о его существовании.
Стандарт DOM Events описывают 3 фазы распространения событий
- Capturing phase — фаза захвата, событие следует к элементу
- Target phase — событие достигает целевого элемента
- Bubbling phase — событие возвращается обратно
Для примера из картинки это будет так:
- Capturing phase: для клика по <td> событие сначала проходит по цепочке предков от корня до элемента
- Target phase: достигает цели и переключается
- Bubbling phase: событие возвращается и по пути снова вызывает свои обработчики
Event Bubbling и Capturing
Event Bubbling (по умолчанию) используется чаще всего в отличие от Event Capturing. Тем не менее, знать про обе фазы прохождения событий не будет лишним.
elem.addEventListener(..., {capture: true})
// или только "true" это алиас для {capture: true}
elem.addEventListener(..., true)
Таким образом, получаем 2 возможных варианта перехвата и обработки события:
- false (по умолчанию), когда событие уже возвращается обратно от элемента
- true – событие только направляется от корня документа к элементу
Клик по элементу <p>
, продемонстрирует прохождение события:
- HTML → BODY → FORM → DIV (сapturing phase) фаза захвата, событие следует к элементу
- P (target phase) событие достигает целевого элемента
- DIV → FORM → BODY → HTML (bubbling phase) событие возвращается обратно
Что ещё нужно знать о Event Bubbling
Почти у всех событий есть bubbling phase, за редким исключением. Например, событие bubbling phase отсутствует у focus.
Что ещё нужно знать о Event Capturing
Эта фаза событий используется не часто.
Свойства события: target
, currentTarget
, eventPhase
target
- относится к элементу DOM, который вызвал событие
- оно не меняется в течение времени жизни события
currentTarget (this)
ссылка на элемент DOM, которому назначен метод-перехватчик события
Обработчик клика у элемента FORM будет перехватывать клики по любому элементу внутри него. Независимо от того, где произошел клик, он всплывёт до <form>
и запустит обработчик. e.currentTarget
здесь будет элемент <form>
, потому, что ему назначен метод-обработчик. e.target
– любой элемент внутри <form>
, по которому был сделан клик.
eventPhase
Свойство события eventPhase
возвращает число, указывающее, какая фаза потока событий в настоящее время оценивается.
Число представлено четырьмя числовыми константами:
- NONE
- CAPTURING_PHASE поток событий находится в фазе захвата
- AT_TARGET поток событий находится в целевой фазе, то есть событие достигло цели
- BUBBLING_PHASE поток событий находится в фазе возвращения
Прерывание событий
stopPropagation()
Метод stopPropagation
у объекта Event предназначен для предотвращения распространения события (bubbling). Объект Event предоставляет этот метод параметром в виде функции обратного вызова. Но лучше не останавливать событие с помощью event.stopPropagation()
без особой необходимости. В большинстве случаев это бесполезно и может привести к неожиданному отсутствию события там, где возникла необходимость его обнаруживать. Иногда лучше позволить событию спокойно завершить весь свой жизненный цикл.
function handleClick(event) {
event.stopPropagation();
// какой-то код
}
Если у элемента есть несколько обработчиков для одного события, то когда один из них останавливает (метод stopPropagation()
) распространение, другие по-прежнему выполнятся.
stopImmediatePropagation()
В отличие от stopPropagation()
, вызов метода stopImmediatePropagation()
остановит распространение события и предотвратит выполнение остальных обработчиков.
Итог
При возникновении, событие DOM начинает перемещаться от корня документа к элементу, который его инициировал. Доходит до элемента-инициатора и возвращается обратно. По пути к инициатору и обратно любой элемент может перехватить событие и как-то его обработать. У события есть методы для остановки его распространения. У события есть несколько свойств для идентификации его состояния в момент перехвата.
dom-event-flow-and-javascript-event-flows-bubbling-capturing-target.