Популярная викторина: какова цель третьего параметра, передаваемого в addEventListener()
?
Не смущайтесь, если вы думаете, что addEventListener()
принимает только два параметра или, возможно, просто всегда жестко запрограммировал значение false
, смутно понимая, что это как-то связано с… пузырьками?
Более настраиваемый addEventListener().
Метод addEventListener()
прошел долгий путь с момента появления Интернета, и его новые функциональные возможности настраиваются с помощью расширенной версии этого третьего параметра. Недавние изменения в определении метода позволяют разработчикам предоставлять дополнительные параметры через объект конфигурации , сохраняя при этом обратную совместимость при наличии логического параметра или когда параметр не указан.
Мы рады сообщить, что в Chrome 55 добавлена поддержка параметра once
в этом объекте конфигурации, наряду с passive
( реализованными в Chrome 51 ) и опциями capture
( реализованными в Chrome 49 ). Например:
element.addEventListener('click', myClickHandler, {
once: true,
passive: true,
capture: true
});
Вы можете комбинировать и сопоставлять эти параметры в соответствии с вашим собственным вариантом использования.
Преимущества уборки за собой
Вот синтаксис использования опции new once
, но что это вам даст? Короче говоря, он дает вам прослушиватель событий, адаптированный к сценариям использования «один и готово».
По умолчанию прослушиватели событий сохраняются после первого вызова, что и нужно для некоторых типов событий — например, для кнопок, которые можно нажимать несколько раз. Однако для других целей наличие прослушивателя событий не обязательно и может привести к нежелательному поведению, если у вас есть обратный вызов, который должен выполняться только один раз. Разработчики, придерживающиеся гигиенических требований, всегда имели возможность использовать removeEventListener()
для явной очистки, следуя таким шаблонам, как:
element.addEventListener('click', function cb(event) {
// ...one-time handling of the click event...
event.currentTarget.removeEventListener(event.type, cb);
});
Эквивалентный код, использующий новый параметр once
, более понятен и не требует отслеживать имя события ( event.type
в предыдущем примере) или ссылку на функцию обратного вызова ( cb
). :
element.addEventListener('click', function(event) {
// ...one-time handling of the click event...
}, {once: true});
Очистка обработчиков событий также может повысить эффективность использования памяти за счет уничтожения области, связанной с функцией обратного вызова, позволяя собирать мусор любым переменным, захваченным в этой области . Вот один из таких примеров, когда это может иметь значение:
function setUpListeners() {
var data = ['one', 'two', '...etc.'];
window.addEventListener('load', function() {
doSomethingWithSomeData(data);
// data is now part of the callback's scope.
});
}
По умолчанию обратный вызов прослушивателя событий load
останется в области видимости после завершения работы, даже если он больше никогда не будет использоваться. Поскольку переменная data
используется внутри обратного вызова, она также останется в области видимости и никогда не будет собирать мусор. Однако если обратный вызов был удален с помощью параметра once
, как сама функция, так и все, что сохраняется в ее области действия, потенциально могут стать кандидатами на сбор мусора.
Поддержка браузера
Chrome 55+, Firefox 50+ и технологическая предварительная версия Safari 7+ имеют встроенную поддержку опции once
.
Многие библиотеки пользовательского интерфейса JavaScript предоставляют удобные методы для создания прослушивателей событий, а некоторые имеют ярлыки для определения одноразовых событий, наиболее заметным из которых является метод jQuery one()
. Также доступен полифилл, как часть библиотеки dom4
Андреа Джаммарки .
Спасибо
Спасибо Ингвару Степаняну за отзыв о примере кода в этом посте.