0Pricing
JavaScript Academy · Урок

Фазы перехвата и всплытия

Разберитесь, как события проходят через DOM.

«Фазы перехвата и всплытия» — бесплатный урок JavaScript Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения JavaScript Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс JavaScript Academy содержит 4 уроков всего.

Два прохода по DOM

Когда Вы щёлкаете по элементу, событие возникает не только на нём. Оно проходит по дереву DOM в две фазы: фазу захвата (сверху вниз, от document к целевому элементу) и фазу всплытия (снизу вверх, от целевого элемента обратно к document).

<div id="outer">
  <button id="inner">Click</button>
</div>

По умолчанию — всплытие

По умолчанию addEventListener слушает события во время фазы всплытия. При щелчке по внутренней кнопке сначала срабатывает её обработчик, затем обработчик родителя, потом обработчик прародителя и так далее до document.

inner.addEventListener("click", () => console.log("inner"));
outer.addEventListener("click", () => console.log("outer"));
// Click inner -> logs: "inner" then "outer"

Включение захвата

Передайте третий аргумент true (или { capture: true }), чтобы вместо этого слушать события во время фазы захвата. Обработчики захвата выполняются сверху вниз, до любых обработчиков всплытия.

outer.addEventListener("click", () => console.log("outer capture"), true);
inner.addEventListener("click", () => console.log("inner bubble"));
// Click inner -> "outer capture" then "inner bubble"

Полный порядок

Для щелчка по #inner, если обработчики установлены в обеих фазах, порядок такой: фаза захвата сверху вниз, затем целевой элемент, затем фаза всплытия снизу вверх.

  • захват документа
  • захват внешнего элемента
  • внутренний элемент (цель)
  • всплытие внешнего элемента
  • всплытие документа

event.target и event.currentTarget

event.target — это элемент, который фактически вызвал событие, то есть место щелчка. event.currentTarget — элемент, чей обработчик выполняется в данный момент. В обработчике родителя при всплытии они различаются.

outer.addEventListener("click", (e) => {
  console.log(e.target.id);        // "inner" - where click occurred
  console.log(e.currentTarget.id); // "outer" - listener owner
});

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

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

inner.addEventListener("click", (e) => {
  e.stopPropagation();
  console.log("handled here only");
});
outer.addEventListener("click", () => console.log("never runs"));

stopImmediatePropagation

stopPropagation() по-прежнему позволяет выполняться другим обработчикам на том же элементе. Чтобы также заблокировать соседние обработчики на этом элементе, используйте event.stopImmediatePropagation().

inner.addEventListener("click", (e) => {
  e.stopImmediatePropagation();
  console.log("first only");
});
inner.addEventListener("click", () => console.log("blocked"));

preventDefault отличается

Не путайте preventDefault() с stopPropagation(). preventDefault() отменяет стандартное действие браузера (переход по ссылке, отправку формы), но НЕ останавливает всплытие события.

link.addEventListener("click", (e) => {
  e.preventDefault();  // do not navigate
  // event still bubbles to parents
});

Почему захват используется редко

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

Проверка фазы

event.eventPhase сообщает, какая фаза активна: 1 — захват, 2 — на целевом элементе, 3 — всплытие. Обычно это не требуется, но помогает при отладке сложных цепочек обработчиков.

el.addEventListener("click", (e) => {
  console.log(e.eventPhase); // 1, 2, or 3
}, true);

Не все события всплывают

Большинство событий пользовательского интерфейса (click, input, keydown) всплывают. Некоторые события по умолчанию не всплывают, например focus, blur и mouseenter. Для них используйте варианты со всплытием (focusin, focusout) или фазу захвата.

Быстрая проверка

Проверьте, насколько хорошо Вы понимаете фазы событий.

Итоги

События проходят сначала фазу захвата (вниз), а затем фазу всплытия (вверх). По умолчанию обработчики используют всплытие; передайте true, чтобы включить захват. e.target — источник события, а e.currentTarget — элемент, которому принадлежит обработчик. Используйте stopPropagation(), чтобы остановить распространение, и preventDefault(), чтобы отменить стандартные действия. Эти две фазы лежат в основе делегирования событий.

Часто задаваемые вопросы

Урок «Фазы перехвата и всплытия» бесплатный?

Да — полный текст урока «Фазы перехвата и всплытия» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс JavaScript Academy, подпишись на CoddyKit PRO. Курс JavaScript Academy содержит 4 уроков всего.

Чему я научусь в уроке «Фазы перехвата и всплытия»?

Разберитесь, как события проходят через DOM. Ты практикуешь JavaScript Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать JavaScript Academy?

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

Сколько времени занимает урок «Фазы перехвата и всплытия»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке JavaScript Academy?

Да. Каждый урок JavaScript Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Фазы перехвата и всплытия
  2. Шаблон делегирования событий
  3. Динамические списки с делегированием
  4. Пользовательские события
← Назад к JavaScript Academy