Однажды прослушиватель событий

Популярная викторина: какова цель третьего параметра, передаваемого в 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 Андреа Джаммарки .

Спасибо

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