#javascript #html
#javascript #HTML
Вопрос:
Я могу заставить элементы выполнять свои обработчики на этапе захвата следующим образом:
elem.addEventListener('event', handler, {once: false, capture: true});
Установка третьего аргумента в true
также работает — есть ли очевидная причина, почему? Имеет ли выполнение этого таким образом какие-либо побочные эффекты?
Ответ №1:
Логический параметр был оригинальным способом, которым он работал, до того, как был введен options
объект. Вот причина, по которой он (все еще) работает: для обратной совместимости.
Смотрите документы:
Синтаксис
target.addEventListener(type, listener [, options]); target.addEventListener(type, listener [, useCapture]);
Вы можете либо передать логическое значение useCapture
(оно существует уже более длительное время), либо объект options, который позволяет вам указывать capture
также и другие вещи (например, once
).
Таким образом, addEventListener(..., true)
это то же самое, что и addEventListener(..., { capture: true })
, и побочных эффектов нет.
options
Форма объекта существует с ~ 2016 года. Проверьте caniuse, чтобы увидеть, какие клиенты поддерживают его.
Ответ №2:
Если у вас нет других прослушивателей событий, которые могут выполнять какие-либо действия с событием или страницей, то, как правило, не имеет значения, куда вы подключаете своего прослушивателя. Если это единственный прослушиватель, вы можете прикрепить его к элементу, или к одному из его родителей, или к документу или window
, и к любому из тех, кто находится на этапе создания пузырьков или захвата — и в большинстве случаев это не будет иметь значения.
Основное назначение прослушивателя захвата — установить порядок, в котором выполняются обработчики событий. Когда событие отправляется элементу, оно сначала захватывает вниз от window
, запуская прослушиватели захвата на window
, затем на document
, затем на промежуточных элементах, пока не достигнет самого глубокого элемента, который привел к событию. На самом глубоком элементе будут запущены как прослушиватели захвата, так и загрузочные прослушиватели в том порядке, в котором они были прикреплены. Затем событие начнет «пузыриться», запуская прослушиватели пузырьков для этого самого глубокого элемента, затем для промежуточных элементов, затем для документа, а затем для окна.
Чтобы проиллюстрировать, посмотрите, как прослушиватель захвата запускается первым здесь, когда слушатели подключены к родительскому:
document.addEventListener('click', () => console.log('bubbling'));
document.addEventListener('click', () => console.log('capturing (method 1)'), true);
document.addEventListener('click', () => console.log('capturing (method 2)'), { capture: true });
<button>click</button>
Если элемент, к которому подключается прослушиватель, является тем же элементом, который отправляет событие (например, если у вас есть button
элемент без дочерних элементов, на который нажимается), то захват против пузырьков не имеет никакого эффекта — все прослушиватели будут выполняться в том порядке, в котором они были подключены, независимо от useCapture
.
Прослушиватели с пузырьками могут использоваться для предотвращения всплывания события вверх и запуска родительских прослушивателей. Аналогично, захват прослушивателей может предотвратить захват события вниз и запуск дочерних прослушивателей.
window.addEventListener('click', (e) => {
e.stopPropagation();
console.log('capturing, stopPropagation')
}, true);
document.querySelector('button').addEventListener('click', () => console.log('at target'));
<button>click</button>
Выше прослушиватель захвата вызывался stopPropagation
для события, предотвращая его распространение вниз на дочерний прослушиватель, который был бы запущен позже, если бы не stopPropagation
.
Для третьего аргумента addEventListener
вы можете использовать { capture: useCapture }
или просто useCapture
в качестве аргумента, согласно спецификации:
Метод addEventListener (тип, обратный вызов, параметры) при вызове должен выполнять следующие шаги:
- Пусть capture, passive и once будут результатом сглаживания дополнительных опций.
Где «сглаживание больше» делает:
- Пусть захват будет результатом сглаживания параметров.
Где «сглаживание» делает:
- Если значение options является логическим, то верните значение options.
- Верните параметры захвата.
Комментарии:
1. Это хороший ответ на вопрос «в чем разница между прослушивателем событий, запускаемым на этапе захвата, и фазой пузырьков», но это не то, что было задано. Казалось бы, OP уже знает, что делает этап захвата. Они спросили конкретно о том, как получилось, что 3-й аргумент
true
вместо{ capture: true }
также работает, на что вы не ответили.