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

Зачем нужны три фазы событий?

1.0 Junior🔥 121 комментариев
#JavaScript Core

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

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

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

Три фазы событий в JavaScript

Три фазы событий (Event phases) — это механизм, который позволяет обрабатывать события на разных уровнях иерархии DOM элементов. Это дает большую гибкость и контроль над обработкой событий.

Что такое три фазы

  1. Capturing (Захват) — событие движется вниз от корня DOM к целевому элементу
  2. Target (Цель) — событие достигло целевого элемента
  3. Bubbling (Всплытие) — событие движется вверх от целевого элемента к корню

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

const parent = document.querySelector('.parent')
const child = document.querySelector('.child')

// Фаза CAPTURE
parent.addEventListener('click', () => {
  console.log('Parent CAPTURE phase')
}, true)

// Фаза BUBBLE
child.addEventListener('click', () => {
  console.log('Child TARGET/BUBBLE phase')
}, false)

parent.addEventListener('click', () => {
  console.log('Parent TARGET/BUBBLE phase')
}, false)

addEventListener(event, handler, useCapture)

Третий параметр определяет фазу:

// true = слушаем на фазе CAPTURE
element.addEventListener('click', handler, true)

// false = слушаем на фазе BUBBLE (по умолчанию)
element.addEventListener('click', handler, false)
element.addEventListener('click', handler)

Зачем нужны три фазы

1. Event Delegation (делегирование событий)

Позволяет обрабатывать события на родительском элементе:

document.body.addEventListener('click', (e) => {
  if (e.target.matches('.button')) {
    handler(e)
  }
})

Преимущества:

  • Экономия памяти (один слушатель вместо множества)
  • Работает для динамически добавленных элементов
  • Проще управлять

2. Контроль порядка обработки

Создаёт предсказуемый порядок выполнения обработчиков. События идут: capture -> target -> bubble.

3. Перехват и остановка распространения

child.addEventListener('click', (e) => {
  e.stopPropagation()
  console.log('Child clicked')
})

parent.addEventListener('click', () => {
  console.log('Parent clicked')
})

С stopPropagation() обработчик parent не будет вызван.

4. Приоритизация обработчиков

Используя capture, можно обработать событие ДО того, как его обработает целевой элемент.

Практические примеры

Пример 1: Модальное окно

const dialog = document.querySelector('.dialog')
const backdrop = document.querySelector('.backdrop')

backdrop.addEventListener('click', (e) => {
  if (e.target === backdrop) {
    dialog.close()
  }
})

Пример 2: Таблица с кликами по строкам

const table = document.querySelector('table')

table.addEventListener('click', (e) => {
  const row = e.target.closest('tr')
  if (row) {
    console.log('Clicked row:', row.textContent)
  }
})

e.stopPropagation() vs e.preventDefault()

element.addEventListener('click', (e) => {
  e.stopPropagation()
  e.preventDefault()
})

stopPropagation — останавливает распространение события вверх по DOM. preventDefault — отменяет действие по умолчанию.

Итоговое резюме

Три фазы событий нужны для:

  • Делегирования событий
  • Контроля порядка выполнения обработчиков
  • Перехвата и остановки распространения
  • Приоритизации обработки на разных уровнях DOM

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