> Можно ли отлавливать события на фазе погружения (capture phase) в JavaScript и как это сделать (JavaScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: intelsy, Сбер, HolyWeb
Стек: JavaScript
> Пример ответа
Короткий ответ
Да, можно. Для этого в addEventListener третьим аргументом передаётся объект с опцией capture: true или просто true. Событие на фазе capture обрабатывается до фазы target и bubbling, что позволяет перехватывать событие до того, как оно достигнет целевого элемента. Это полезно для глобальных обработчиков, отмены событий на ранней стадии или реализации паттерна event delegation с контролем порядка.
Подробное объяснение
Стандарт DOM Events определяет три фазы распространения события: capture (погружение), target (цель) и bubbling (всплытие). По умолчанию обработчики срабатывают на фазе bubbling. Чтобы повесить обработчик на фазу capture, нужно указать это явно.
Механизм работы: событие сначала движется от корня документа вниз к целевому элементу (capture phase), затем достигает цели (target phase), после чего поднимается обратно (bubbling phase). Обработчики на capture phase срабатывают при движении вниз, до того как событие достигнет целевого элемента.
Важно: не все события поддерживают capture phase (например, focus, blur, scroll не всплывают, но могут быть перехвачены на capture). Также capture phase нельзя отключить - это часть спецификации, но можно контролировать, какие обработчики на ней висят.
На практике
Capture phase используется в нескольких сценариях:
- Перехват событий до их обработки целевым элементом (например, для логирования или отмены)
- Реализация глобальных обработчиков, которые должны срабатывать раньше любых других
- Обработка событий, которые не всплывают (например,
focusна элементах формы) - В библиотеках и фреймворках для реализации собственных систем событий (например, React использует capture phase для synthetic events)
Типичный кейс: нужно предотвратить клик по любому элементу внутри контейнера, кроме самого контейнера. На capture phase можно проверить целевой элемент и вызвать stopPropagation().
Пример кода
JAVASCRIPT// Базовый синтаксисelement.addEventListener('click', handler, true);// илиelement.addEventListener('click', handler, { capture: true });// Пример с отменой на capture phasedocument.addEventListener('click', (event) => {if (event.target.closest('.protected')) {event.stopPropagation();console.log('Клик перехвачен на capture phase');}}, true);// Пример с обработкой focus (не всплывает)document.addEventListener('focus', (event) => {console.log('Фокус получен элементом:', event.target);}, true);
Как отвечать на собеседовании
Начни с чёткого ответа "да, можно" и сразу назови синтаксис. Затем объясни фазы распространения событий, чтобы показать понимание модели DOM Events. Приведи практический пример использования - это демонстрирует опыт. Упомяни, что capture phase полезна для событий, которые не всплывают. Если спросят про stopPropagation() - отметь, что он работает и на capture phase, но блокирует только последующие обработчики на этой фазе и на target, а bubbling не затрагивается (если не вызван на target phase).
Что проверяет интервьюер
- Понимание модели событий DOM (три фазы)
- Знание синтаксиса addEventListener
- Умение применять capture phase в реальных задачах
- Понимание разницы между capture и bubbling
- Знание ограничений (какие события не всплывают, но работают на capture)
Типичные ошибки
- Путаница между capture и bubbling фазами
- Использование
return falseдля остановки распространения (работает только в jQuery) - Забывают, что
stopPropagation()на capture phase не отменяет bubbling, если событие уже дошло до target - Думают, что capture phase есть у всех событий (например,
mouseenter/mouseleaveне имеют capture) - Передача
trueкак третьего аргумента, когда нужен объект с опциями (может привести к путанице при удалении обработчика)
> Похожие задачи по frontend
Как реализовать добавление рандомного товара в корзину и удаление его из ассортимента по клику?
Какие способы выполнения HTTP-запросов в браузере на JavaScript?
Каков порядок вывода консольных логов при использовании setTimeout и промисов в JavaScript
Как проверить тег элемента в обработчике события клика в JavaScript
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью