Detektor zdarzeń

Szybki quiz: do czego służy trzeci parametr przekazywany do addEventListener()?

Nie wstydź się, jeśli uważasz, że funkcja addEventListener() przyjęła tylko 2 parametry lub zakodowała na stałe wartość false, podając niejasne informacje, że ma to związek z dymkami.

Bardziej konfigurowalna funkcja addEventListener()

Metoda addEventListener() bardzo się zmieniła od początków korzystania z internetu, a jej nowe funkcje są konfigurowane za pomocą superefektywnej wersji trzeciego parametru. Ostatnie zmiany w definicji metody umożliwiają programistom udostępnianie dodatkowych opcji za pomocą obiektu konfiguracji przy zachowaniu zgodności wstecznej w przypadku, gdy występują parametry logiczne lub nie określono opcji.

Z przyjemnością informujemy, że Chrome 55 dodaje obsługę opcji once w tym obiekcie konfiguracji oraz opcji passive (wprowadzonych 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 je łączyć i dopasowywać do swoich potrzeb.

Zalety sprzątania po sobie

Tak wygląda składnia nowej opcji once, ale co z tego wynika? Krótko mówiąc, ten odbiornik jest dostosowany do potrzeb każdego zastosowania.

Domyślnie detektory zdarzeń pozostają aktywne po pierwszym wywołaniu, co jest odpowiednie w przypadku niektórych typów zdarzeń, np. przycisków, które można kliknąć wielokrotnie. Jednak w innych zastosowaniach pozostawienie odbiornika zdarzeń nie jest konieczne i może prowadzić do niepożądanego zachowania, jeśli masz wywołanie zwrotne, które musi być wykonywane tylko raz. Deweloperzy, którzy dbają o higienę, zawsze mogli skorzystać z removeEventListener() do jednoznacznego czyszczenia danych, korzystając z następujących wzorców:

element.addEventListener('click', function cb(event) {
    // ...one-time handling of the click event...
    event.currentTarget.removeEventListener(event.type, cb);
});

Odpowiedni kod, z wykorzystaniem nowego parametru once, jest bardziej przejrzysty i nie wymaga śledzenia nazwy zdarzenia (w poprzednim przykładzie event.type) ani odniesienia do funkcji wywołania zwrotnego (cb):

element.addEventListener('click', function(event) {
    // ...one-time handling of the click event...
}, {once: true});

Oczyszczanie modułów obsługi zdarzeń może też zwiększyć wydajność pamięci przez zniszczenie zakresu powiązanego z funkcją wywołania zwrotnego, co umożliwi zbieranie bezużytecznych zmiennych przechwyconych w tym zakresie. Oto jeden z przykładów, w których może to wpłynąć na różnicę:

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, mimo że nie jest już używane. Zmienna data jest używana w wywołaniu zwrotnym, więc pozostaje w zakresie i nigdy nie jest usuwana z pamięć. Jeśli jednak wywołanie zwrotne zostało usunięte za pomocą parametru once, zarówno funkcja, jak i wszystko, co jest utrzymywane za pomocą jego zakresu, potencjalnie będą kandydatami do czyszczenia pamięci.

Obsługiwane przeglądarki

Chrome w wersji 55 i nowszych, Firefox w wersji 50 i nowszych oraz wersja przedpremierowa technologii w wersji 7 Safari mają natywną obsługę opcji once.

Wiele bibliotek interfejsu JavaScript udostępnia wygodne metody tworzenia odbiorników, a niektóre mają skróty do definiowania zdarzeń jednorazowych. Najbardziej znana jest metoda one() oferowana w jQuery. Dostępny jest też kod polyfill w bibliotece dom4 Andrei Giammarchi.

Dziękujemy

Dziękujemy Ingvarowi Stepanyan za przesłanie opinii na temat przykładowego kodu w tym poście.