← Назад к вопросам

С чего начинается распространение события

2.0 Middle🔥 172 комментариев
#JavaScript Core#Браузер и сетевые технологии

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

С чего начинается распространение события в браузере?

Распространение события в браузере начинается с фазы захвата (capturing phase) — это первый этап жизненного цикла события, когда оно движется от корневого элемента документа вниз по дереву DOM к целевой цели события (target element).

Механизм распространения события: три фазы

Полный цикл распространения события состоит из трех последовательных фазы:

  1. Фаза захвата (Capturing Phase) — событие начинает движение от самого верхнего узла DOM (обычно window или document) вниз по дереву, через всех родительских элементов, к целевой цели события.
  2. Фаза цели (Target Phase) — событие достигает целевой цели элемента, на котором оно фактически произошло (например, кликнутый элемент).
  3. Фаза всплытия (Bubbling Phase) — событие поднимается обратно вверх по дереву DOM, от целевой цели к корневому элементу.

Пример дерева DOM и пути события

Рассмотрим следующую структуру HTML:

<!DOCTYPE html>
<html>
<body>
  <div id="outer">
    <div id="inner">
      <button id="button">Кликнуть</button>
    </div>
  </div>
</body>
</html>

При клике на <button id="button"> событие click будет распространяться так:

Путь события:
1. Capturing Phase: window → document → body → div#outer → div#inner → button#button
2. Target Phase: button#button (целевая цель)
3. Bubbling Phase: button#button → div#inner → div#outer → body → document → window

Как работает фаза захвата в коде

Для обработки события на фазе захвата необходимо использовать третий параметр addEventListeneroptions или булевый useCapture, установленный в true.

Пример с useCapture:

const outerDiv = document.getElementById('outer');
const innerDiv = document.getElementById('inner');
const button = document.getElementById('button');

// Обработчик на фазе захвата (useCapture = true)
outerDiv.addEventListener('click', function(event) {
  console.log('Capturing: outerDiv');
}, true);

innerDiv.addEventListener('click', function(event) {
  console.log('Capturing: innerDiv');
}, true);

button.addEventListener('click', function(event) {
  console.log('Target Phase: button');
});

// Обработчик на фазе всплытия (useCapture = false или опущен)
outerDiv.addEventListener('click', function(event) {
  console.log('Bubbling: outerDiv');
}, false); // или просто без третьего параметра

При клике на кнопку вывод в консоли будет:

Capturing: outerDiv
Capturing: innerDiv
Target Phase: button
Bubbling: innerDiv (если есть такой обработчик)
Bubbling: outerDiv

Важные особенности и правила

  • По умолчанию обработчики работают на фазе всплытия: если не указать useCapture или options.capture, addEventListener регистрирует обработчик на фазе всплытия.
  • Современный синтаксис с options: можно использовать объект настроек, что позволяет указать дополнительные параметры, например passive для оптимизации скролла.
element.addEventListener('click', handler, {
  capture: true,   // обработчик на фазе захвата
  passive: true,   // никогда не будет вызван preventDefault()
  once: true       // обработчик выполнится только один раз
});
  • Целевая цель фиксируется: элемент event.target всегда остается тем элементом, на котором событие произошло, независимо от текущей фазы. event.currentTarget указывает на элемент, на котором сейчас выполняется обработчик.
  • Прерывание распространения: методы event.stopPropagation() и event.stopImmediatePropagation() могут остановить распространение события, но важно понимать их различия:
    • stopPropagation() — предотвращает дальнейшее движение события к следующим элементам на текущей и последующих фазах.
    • stopImmediatePropagation() — также предотвращает вызов других обработчиков события, зарегистрированных на текущем элементе для этой же фазы.

Практическое значение фазы захвата

Фаза захвата часто используется для:

  • Глобального перехвата событий на верхнем уровне документа перед тем, как они достигнут целевых элементов.
  • Реализации паттернов типа Event Delegation на ранней стадии, хотя делегирование обычно работает на всплытии.
  • Создания систем мониторинга или анализа поведения пользователя, где нужно гарантированно обработать событие перед любыми другими обработчиками на целевых элементах.

Пример делегирования с захватом:

document.addEventListener('click', function(event) {
  if (event.target.tagName === 'BUTTON') {
    console.log('Захвачен клик на button до его собственных обработчиков');
    // Здесь можно, например, логировать действия
  }
}, true);

Итог

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

С чего начинается распространение события | PrepBro