removeEventListener Event Handler entbinden
Zu addEventListener gibt es ein Gegenstück removeEventListener, das den Event Handler vom Event entbindet oder entkoppelt. removeEventListener räumt auf und entfernt das Event aus dem Ereignishorizont.
let elem = document.getElementById('elem'); // Event Handler auf elem ansetzen elem.addEventListener("click", myFunction); // Event Handler von elem entfernen elem.removeEventListener("click", myFunction);
removeEventListener funktioniert nur bei externen Funktionsaufrufen. Wurde der Event Handler durch eine anonyme Funktion aktiviert, funktioniert removeEventListener nicht.
Gibt man der anonymen Funktion allerdings einen Namen, entsteht eine Callback-Funktion und der Event Handler kann entfernt werden.
elem.addEventListener ("click", function removeText () { this.innerHTML = ""; this.removeEventListener ("click", removeText); });
Beispiel: removeEventListener bei mouseover
Bei einer Reihe von Events – z.B. bei einem mouseover – reicht es nicht, wenn sich der Event Handler um das Event selber kümmert. Gerade beim mouseover muss u.U. auch das mouseout-Event abgefangen werden.
const scaleup = document.querySelector(".scaleup1"); scaleup.addEventListener ("mouseover", function (evt) { if (evt.target.className === "scale") { const elem = document.createElement ("DIV"); elem.className = "preview"; evt.target.parentNode.appendChild(elem); const myImg = document.createElement("IMG"); const imgSrc = evt.target.src.replace("200.jpg","600.jpg"); myImg.src = imgSrc; elem.appendChild (myImg); } });
Bei jedem mouseover würde erneut ein Vorschaubild angehangen. Also muss auch auf das mouseout-Event gehorcht werden.
Um beim mouseout das angehängte div.preview zu entfernen, muss nach elem.appendChild (myImg); vor der schließenden geschweiften Klammer ein weiterer EventListener eingesetzt werden.
… elem.appendChild (myImg); evt.target.addEventListener ("mouseout", function handler (eve) { const preview = eve.target.parentNode.querySelector("div.preview"); preview.parentNode.removeChild (preview); }, false); }
Das würde zwar auf den ersten Blick Abhilfe schaffen, aber zu einer Flut von Fehlern in der Console führen:
- TypeError: null is not an object (evaluating 'preview.parentNode') oder
- Uncaught TypeError: Cannot read property 'parentNode' of null oder
- TypeError: preview is null
Da bleiben also Events unter dem Event Listener weiterhin aktiv. Der EventListener muss entfernt werden. Dafür ist addEventListener nicht mit einer anonymen Funktion aufgerufen worden, sondern die Funktion hat einen Namen: handler.
evt.target.addEventListener ("mouseout", function handler (eve) { const preview = eve.target.parentNode.querySelector("div.preview"); preview.parentNode.removeChild (preview); evt.target.removeEventListener ("mouseout", handler, false); }, false);
addEventHandler mit once: true
Statt den Event Listener mit removeEventListener zu beenden, kann die neuere Option once in addEventListener eingesetzt werden. Das hält den Code übersichtlicher.
evt.target.addEventListener ("mouseout", function (eve) { const preview = eve.target.parentNode.querySelector("div.preview"); preview.parentNode.removeChild (preview); }, {once: true});
oder allgemein:
elem.addEventListener('click', function (event) {
// nur einmal auszuführen
}, {once: true});