JavaScriptDOM i zdarzenia

EventTarget.removeEventListener()

Odpina funkcję obsługi zdarzenia dodaną wcześniej przez addEventListener(). Wymaga tej samej funkcji i tego samego typu zdarzenia.

Zwraca
undefined
Na tej stronie

Przykład

#
JavaScript
const like = document.querySelector('#like')
const lock = document.querySelector('#lock')
let likes = 0

function addLike() {
  likes += 1
  console.log('Polubienia:', likes)
}

like.addEventListener('click', addLike)

lock.addEventListener('click', () => {
  like.removeEventListener('click', addLike)
  console.log('Polubienia zablokowane')
})

like.click()
lock.click()
like.click()
Konsola
Polubienia: 1
Polubienia zablokowane

Ostatnie like.click() niczego nie wypisuje, bo funkcja addLike jest już odpięta. Kliknięcie przycisku „Polub lekcję” w podglądzie też nic nie zmieni.

Definicja i zastosowanie

#

Metoda removeEventListener() usuwa obsługę zdarzenia zarejestrowaną wcześniej metodą addEventListener(). Po jej wywołaniu funkcja przestaje reagować na dane zdarzenie: przycisk przestaje liczyć kliknięcia, a dokument przestaje nasłuchiwać skrótów klawiszowych.

Przeglądarka rozpoznaje obsługę do usunięcia po trzech rzeczach: typie zdarzenia, funkcji i fazie, czyli opcji capture. Musisz przekazać dokładnie tę samą funkcję (to samo odwołanie), a nie inną funkcję o identycznym kodzie. Dlatego obsługę, którą zamierzasz kiedyś odpiąć, zapisz w zmiennej albo w nazwanej funkcji. Funkcji anonimowej wpisanej bezpośrednio w addEventListener() nie da się usunąć.

Jeśli obsługa była dodana z capture: true, przy usuwaniu też podaj capture: true. Pozostałe opcje, takie jak once czy passive, nie mają tu znaczenia. Próba usunięcia obsługi, której nie ma, nie powoduje błędu, po prostu nic się nie dzieje. Wygodną alternatywą jest opcja signal w addEventListener(): jedno wywołanie controller.abort() odpina wtedy wszystkie obsługi z tym sygnałem.

Składnia

#
Składnia
target.removeEventListener(type, listener)
target.removeEventListener(type, listener, options)
target.removeEventListener(type, listener, useCapture)

Parametry

#
  • type

    napis

    Typ zdarzenia, np. "click". Musi być taki sam jak przy dodawaniu obsługi.
  • listener

    function

    Ta sama funkcja (to samo odwołanie), która została przekazana do addEventListener().
  • options

    opcjonalny obiekt lub boolean

    Liczy się tylko capture. Jeśli obsługa była dodana z capture: true, podaj tu tę samą wartość.

Więcej przykładów

#
Funkcji anonimowej nie da się odpiąć
JavaScript
const save = document.querySelector('#save')

save.addEventListener('click', () => console.log('Zapisano'))
save.removeEventListener('click', () => console.log('Zapisano'))

save.click()
Konsola
Zapisano

Obie funkcje strzałkowe mają ten sam kod, ale to dwa różne obiekty. removeEventListener() nie znajduje pasującej obsługi, więc niczego nie usuwa.

Opcja capture musi się zgadzać
JavaScript
const menu = document.querySelector('#menu')
const log = (event) => console.log('Kliknięto:', event.target.textContent)

menu.addEventListener('click', log, { capture: true })

menu.removeEventListener('click', log)
menu.children[0].click()

menu.removeEventListener('click', log, { capture: true })
menu.children[1].click()
Konsola
Kliknięto: Kursy

Pierwsze wywołanie szuka obsługi dodanej bez capture, więc funkcja zostaje. Dopiero podanie capture: true ją odpina i kliknięcie w „Ranking” nic już nie wypisuje.

Odpinanie wielu obsług przez AbortController
JavaScript
const nick = document.querySelector('#nick')
const controller = new AbortController()
const { signal } = controller

nick.addEventListener('input', () => console.log('input:', nick.value), { signal })
nick.addEventListener('change', () => console.log('change:', nick.value), { signal })

nick.value = 'Ania'
nick.dispatchEvent(new Event('input'))
nick.dispatchEvent(new Event('change'))

controller.abort()

nick.value = 'Kuba'
nick.dispatchEvent(new Event('input'))
nick.dispatchEvent(new Event('change'))
console.log('Obie obsługi odpięte')
Konsola
input: Ania
change: Ania
Obie obsługi odpięte

Jedno controller.abort() usuwa naraz wszystkie obsługi dodane z tym samym sygnałem. Nie trzeba pamiętać każdej funkcji osobno.

Obsługa przeglądarek

#

Szeroko dostępne

Działa we wszystkich nowoczesnych przeglądarkach, także na telefonach. Możesz używać bez obaw.

  • Chrome
  • Edge
  • Firefox
  • Safari

Dobre praktyki

#
  • Obsługę, którą zamierzasz usunąć, zapisz w zmiennej albo nazwanej funkcji. Przekazanie „takiej samej” funkcji strzałkowej nic nie da.
  • Uważaj na bind(): każde wywołanie this.onClick.bind(this) tworzy nową funkcję. Zapisz wynik raz, np. w polu obiektu, i używaj go przy dodawaniu i usuwaniu.
  • Gdy odpinasz kilka obsług naraz, np. przy zamykaniu okna dialogowego, prościej użyć opcji signal i jednego wywołania controller.abort().

Powiązane hasła

#

Widzisz błąd albo brakuje przykładu? Napisz do nas.