Szybki quiz: do czego służy trzeci parametr przekazywany do funkcji addEventListener()
?
Nie wstydź się, jeśli uważasz, że funkcja addEventListener()
przyjmuje tylko 2 parametry, lub jeśli zawsze zamiast niej używasz zaimplementowanej na stałe wartości false
, mając mgliste pojęcie, że ma ona coś wspólnego z bąbelkami.
bardziej konfigurowalna funkcja addEventListener();
Od początków internetu metoda addEventListener()
przeszła długą drogę, a jej nowa funkcjonalność jest konfigurowana za pomocą wzmocnionej wersji tego trzeciego parametru. Najnowsze zmiany w definicji metody pozwalają deweloperom udostępniać dodatkowe opcje za pomocą obiektu konfiguracji, zachowując przy tym zgodność wsteczną, gdy występuje parametr logiczny lub gdy nie jest określona opcja.
Z przyjemnością informujemy, że Chrome 55 obsługuje opcję once
w tym obiekcie konfiguracji, obok opcji passive
(wdrożonej w Chrome 51) i capture
(wdrożonej w Chrome 49). Na przykład:
element.addEventListener('click', myClickHandler, {
once: true,
passive: true,
capture: true
});
Możesz dowolnie łączyć i dopasowywać te opcje w sposób odpowiedni do Twojego przypadku użycia.
Korzyści z sprzątania po sobie
Oto składnia używania nowej opcji once
. Jakie korzyści Ci to przyniesie? Krótko mówiąc, jest to detekcja zdarzeń dostosowana do przypadków użycia typu „jeden i wystarczy”.
Domyślnie detektory zdarzeń są zachowywane po pierwszym wywołaniu, co jest przydatne w przypadku niektórych typów zdarzeń, np. przycisków, które można klikać wielokrotnie. W innych przypadkach nie jest konieczne utrzymywanie detektorów zdarzeń, a ich użycie może prowadzić do niepożądanego zachowania, jeśli masz funkcję wywołania zwrotnego, która musi być wykonywana tylko raz. Deweloperzy dbający o czystość kodu zawsze mieli możliwość korzystania z funkcji removeEventListener()
, aby wyraźnie porządkować kod, stosując wzorce takie jak:
element.addEventListener('click', function cb(event) {
// ...one-time handling of the click event...
event.currentTarget.removeEventListener(event.type, cb);
});
Odpowiednio kod, który korzysta z nowego parametru once
, jest czystszy i nie wymaga śledzenia nazwy zdarzenia (event.type
w poprzednim przykładzie) ani odwołania do funkcji wywołania zwrotnego (cb
):
element.addEventListener('click', function(event) {
// ...one-time handling of the click event...
}, {once: true});
Oczyszczanie metod obsługi zdarzeń może też zwiększyć wydajność pamięci przez zniszczenie zakresu powiązanego z funkcją wywołania zwrotnego, co pozwala na zebranie wszystkich zmiennych uchwyconych w tym zakresie. Oto przykład, w którym może to mieć znaczenie:
function setUpListeners() {
var data = ['one', 'two', '...etc.'];
window.addEventListener('load', function() {
doSomethingWithSomeData(data);
// data is now part of the callback's scope.
});
}
Domyślnie wywołanie zwrotne detektora zdarzeń load
pozostanie w zakresie po zakończeniu działania, nawet jeśli nigdy więcej nie zostanie użyte. Ponieważ zmienna data
jest używana w obiekcie wywołania zwrotnego, pozostanie w zakresie i nigdy nie zostanie zebrana przez garbage collector. Jeśli jednak wywołanie zwrotne zostanie usunięte za pomocą parametru once
, zarówno sama funkcja, jak i wszystko, co jest utrzymywane w ramach jej zakresu, może zostać uznane za kandydata do usunięcia przez mechanizm garbage collection.
Obsługa przeglądarek
Chrome 55+, Firefox 50+ i Safari Technology Preview 7+ mają wbudowane obsługę opcji once
.
Wiele bibliotek interfejsu użytkownika JavaScript udostępnia wygodne metody tworzenia odbiorców zdarzeń, a niektóre z nich mają skróty do definiowania zdarzeń jednorazowych. Najbardziej znana jest metoda one()
jQuery. W ramach dom4
biblioteki Andrea Giammarchi jest też dostępny polyfill.
Dziękujemy
Dziękujemy Ingvarowi Stepanyanowi za opinię na temat przykładowego kodu w tym poście.