removeEventListener mit bind
Theo der Kaffee
- javascript
Hallo,
kurze Frage:
Ich habe einen Button mit einem EventListener, den ich irgendwann im Code wieder entfernen möchte. Das funktioniert auch, solange ich nicht mit bind
Elemente anhänge, siehe wie folgt:
let btn = document.getElementById("btn");
let Func = (e) => {
e.preventDefault();
console.log("Funktion wird aufgerufen!");
};
// btn.addEventListener("click", Func); // mit dieser Zeile würde removeEventListener "greifen"
btn.addEventListener("click", Func.bind(this)); // hier "greift" removeEventListener nicht, console.log("Funktion wird aufgerufen!") wird nach wie vor aufgerufen
btn.removeEventListener("click", Func);
Warum wird hier also trotz removeEventListener
die Funktion Func
noch aufgerufen?
Danke Theo.
@@Theo der Kaffee
let btn = document.getElementById("btn"); let Func = (e) => { e.preventDefault(); console.log("Funktion wird aufgerufen!"); }; // btn.addEventListener("click", Func); // mit dieser Zeile würde removeEventListener "greifen" btn.addEventListener("click", Func.bind(this)); // hier "greift" removeEventListener nicht, console.log("Funktion wird aufgerufen!") wird nach wie vor aufgerufen btn.removeEventListener("click", Func);
Warum wird hier also trotz
removeEventListener
die FunktionFunc
noch aufgerufen?
“The event listener to be removed is identified using a combination of the event type, the event listener function itself, and various optional options that may affect the matching process.” [MDN]
Wenn die event listener function nicht matcht, wird der EventListener nicht entfernt.
🖖 Stay hard! Stay hungry! Stay alive! Stay home!
Wieso matcht die Funktion nicht, bzw. wie bringe ich sie dazu, zu matchen?
Auch
btn.removeEventListener("click", Func.bind(this));
funktioniert nicht, obwohl die Funktion doch ident mit der Funktion sein sollte, die zuvor angehängt wurde (this
bezieht sich in diesem BSP in beiden Fällen auch auf dasselbe, nämlich das Window Objekt)
Hallo Theo,
nein. Jeder bind erzeugt eine neue gebundene Funktion.
let a = Func.bind(this);
let b = Func.bind(this);
console.log(a == b); // false;
Wenn Du einen mit bind erzeugten Eventhandler entfernen willst, musst Du das Ergebnis von Func.bind speichern und beim remove den gespeicherten Wert angeben.
Oder du musst das this anders in die Funktion hineinbugsieren. Closures sind ein sehr mächtiges Werkzeug in JavaScript und können Dir hier helfen. Für das "wie" müsste man mehr über deine Programmstruktur wissen.
Ich habe gerade keine Lust es auszuprobieren. Aber soweit ich mich erinnere, haben Arrowfunktionen ein transparentes this, d.h. sie bekommen beim Aufruf kein eigenes this sondern verwenden das aus dem Kontext, wo sie definiert wurden. Demnach wäre der .bind möglicherweise nicht nötig.
Rolf
let a = Func.bind(this); let b = Func.bind(this); console.log(a == b); // false;
...macht tatsächlich durchaus Sinn!
Wenn ich daher die Funktion und ihre Argumente in einer Variable also zwischenspeichere, kann ich sie mit removeEventListener
dann auch referenzieren, frei nach dem Motto
let Zwischenspeicher = Func.bind(this); // oder auch mehrere Argumente à la Func.bind(this, foo, bar)
btn.addEventListener("click", Zwischenspeicher);
btn.removeEventListener("click", Zwischenspeicher);
Wäre das ein vertretbarer Ansatz?
Hallo Theo,
Wäre das ein vertretbarer Ansatz?
Wenn das zum Rest deines Programms passt, sicher.
Rolf
Danke Gunnar und speziell Rolf für die späte Hilfe!
Kipp zum Wochenausklang ein kühles Blondes auf euch, MUSS sein