Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Перехват и всплытие JS: DOM API

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

<div>
  <button>Send</button>
</div>
button.addEventListener('click', () => alert('Boom 1!'));
div.addEventListener('click', () => alert('Boom 2!'));

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

Погружение (Capturing)

Когда событие только возникло, оно начинает двигаться по DOM-дереву, начиная от корневого узла, до самого глубокого, на котором произошло событие.

               | |
---------------| |---------------
| div          | |              |
|   -----------| |-----------   |
|   | button   \ /          |   |
|   -------------------------   |
|        Event CAPTURING        |
---------------------------------

Попутно на стадии погружения будут выполнены обработчики, которые были привязаны к этой стадии. Привязка регулируется третьим параметром функции addEventListener.

button.addEventListener('click', () => alert('Boom 1!'), true);
div.addEventListener('click', () => alert('Boom 2!'), true);

Значение true привязывает обработчики к стадии погружения. Получится такой вывод:

Boom 2!
Boom 1!

Всплытие (Bubbling)

После остановки погружения на target элементе, начинается всплытие.

               / \
---------------| |---------------
| div          | |              |
|   -----------| |-----------   |
|   | button   | |          |   |
|   -------------------------   |
|        Event BUBBLING         |
---------------------------------

Именно эта стадия подразумевается при вызове addEventListener без указания третьего параметра.

button.addEventListener('click', () => alert('Boom 1!'));
div.addEventListener('click', () => alert('Boom 2!'));

На ней выполнение обработчиков происходит изнутри наружу:

Boom 1!
Boom 2!

W3C Модель

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

В предыдущем уроке мы познакомились с объектом e.target. Это самый глубокий элемент, до которого идет погружение. Target не меняется в процессе всплытия. Благодаря ему всегда можно узнать, где конкретно произошло событие. Кроме него, доступен объект currentTarget - это элемент, к которому прикреплен данный обработчик. В зависимости от ситуации используется тот или иной.

Event Stages

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

Сделать это можно двумя способами:

  • event.stopPropagation()
  • event.stopImmediatePropagation()

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


Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.
Об обучении на Хекслете

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
900
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 120 курсов, 2000+ часов теории
  • 900 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы Фронтенд-разработчик
Профессия
Разработка фронтенд-компонентов веб-приложений
1 декабря 8 месяцев

Используйте Хекслет по максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг»