Ich habe den folgenden Code, um eventListener hinzuzufügen
area.addEventListener('click',function(event) {
app.addSpot(event.clientX,event.clientY);
app.addFlag = 1;
},true);
Es funktioniert korrekt wie erwartet. Später in einer anderen Funktion habe ich versucht, den Ereignis-Listener mit dem folgenden Code zu entfernen
area.removeEventListener('click',function(event) {
app.addSpot(event.clientX,event.clientY);
app.addFlag = 1;
},true);
Aber der gerade Listener wird nicht entfernt. Warum passiert das? Gibt es ein Problem mit meinem removeEventListener ()? Hinweis: In diesem Bereich befindet sich etwa document.getElementById ('myId').
javascript
events
addeventlistener
Jinu Joseph Daniel
quelle
quelle
Antworten:
Dies liegt daran, dass zwei anonyme Funktionen völlig unterschiedliche Funktionen sind. Ihr
removeEventListener
Argument ist kein Verweis auf das zuvor angehängte Funktionsobjekt.function foo(event) { app.addSpot(event.clientX,event.clientY); app.addFlag = 1; } area.addEventListener('click',foo,true); area.removeEventListener('click',foo,true);
quelle
bind(this)
wird die Signatur ändern. Weisen Sie die Funktion daher immer einervar
After-Bindungthis
zur Verwendung der Funktions-bind
API zu, damit diese invar
verwendet werden kannremoveListener
. Sie werden dieses Problem in Typoskriptfoo(1)
this.onClick = this.onClick.bind(this)
vor jedem Zuhörer, dannbtn.addEventListener('click', this.onClick)
endlichbtn.removeEventListener('click', this.onClick)
Ich finde, dass für das Windows-Objekt der letzte Parameter "true" erforderlich ist. Das Entfernen funktioniert nicht, wenn kein Erfassungsflag vorhanden ist.
quelle
Sie erstellen in beiden Aufrufen zwei verschiedene Funktionen. Die zweite Funktion bezieht sich also in keiner Weise auf die erste, und der Motor kann die Funktion entfernen. Verwenden Sie stattdessen eine gemeinsame Kennung für die Funktion.
var handler = function(event) { app.addSpot(event.clientX,event.clientY); app.addFlag = 1; }; area.addEventListener('click', handler,true);
später können Sie den Handler dann durch Aufrufen entfernen
area.removeEventListener('click', handler,true);
quelle
Um es zu entfernen, speichern Sie die Funktion in einer Variablen oder verwenden Sie einfach eine benannte Funktion und übergeben Sie diese Funktion an den
removeEventListener
Aufruf:function areaClicked(event) { app.addSpot(event.clientX, event.clientY); app.addFlag = 1; } area.addEventListener('click', areaClicked, true); // ... area.removeEventListener('click', areaClicked, true);
quelle
Wenn Sie lokale Variablen an die vom Ereignis-Listener aufgerufene Funktion übergeben möchten, können Sie die Funktion innerhalb der Funktion definieren (um die lokalen Variablen abzurufen) und den Namen der Funktion in der Funktion selbst übergeben. Beginnen wir beispielsweise mit der Funktion, die den Ereignis-Listener mit der App als lokaler Variable hinzufügt. Sie würden eine Funktion innerhalb dieser Funktion schreiben, wie z.
function yourFunction () { var app; function waitListen () { waitExecute(app, waitListen); } area.addEventListener('click', waitListen, true); }
Dann haben Sie das, was Sie brauchen, um es zu entfernen, wenn waitExecute aufgerufen wird.
function waitExecute (app, waitListen) { ... // other code area.removeEventListener('click', waitListen, true); }
quelle
Definieren Sie zuerst Ihren Event Handler.
und dann
area.addEventListener('click',handler); area.removeEventListener('click',handler);
quelle
Ich habe ein Problem mit removeEventListener () festgestellt, das erklärt werden muss.
Ich wollte in der Lage sein, Parameter an Ereignis-Listener zu übergeben, also schrieb ich eine Funktion zum Generieren des Ereignis-Listeners, die wiederum eine zweite Funktion zurückgibt, die meinen beabsichtigten Ereignis-Listener als Rückruf aufruft.
Die vollständige Bibliotheksdatei lautet wie folgt:
//Event handler constants function EventHandlerConstants() { this.SUCCESS = 0; //Signals success of an event handler function this.NOTFUNCTION = 1; //actualHandler argument passed to MakeEventHandler() is not a Function object //End constructor } //MakeEventHandler() //Arguments: //actualHandler : reference to the actual function to be called as the true event handler //selfObject : reference to whatever object is intended to be referenced via the "this" keyword within // the true event handler. Set to NULL if no such object is needed by your true // event handler specified in the actualHandler argument above. //args : array containing the arguments to be passed to the true event handler, so that the true // event handler can be written with named arguments, such as: // myEventHandler(event, arg1, arg2, ... ) // If your function doesn't need any arguments, pass an empty array, namely [], as the // value of this argument. //Usage: //c = new EventHandlerConstants(); //res = MakeEventHandler(actualHandler, selfObject, args); //if (res == c.SUCCESS) // element.addEventListener(eventType, res.actualHandler, true); //or whatever function MakeEventHandler(actualHandler, selfObject, args) { var c = new EventHandlerConstants(); var funcReturn = null; //This will contain a reference to the actual function generated and passed back to //the caller var res = { "status" : c.SUCCESS, "actualHandler" : null }; if (IsGenuineObject(actualHandler, Function)) { res.actualHandler = function(event) { var trueArgs = [event].concat(args); actualHandler.apply(selfObject, trueArgs); }; } else { res.status = c.NOTFUNCTION; //End if/else } //Return our result object with appropriate properties set ... return(res); //End function }
Dann schrieb ich eine kurze Testseite, um herauszufinden, ob dies wie beabsichtigt funktionierte, und erlaubte mir, Ereignishandler nach Belieben hinzuzufügen UND zu entfernen.
Die HTML-Testseite lautet wie folgt:
<!DOCTYPE html> <html> <head> <!-- CSS goes here --> <link rel="stylesheet" type="text/css" href="NewEventTest.css"> <!-- Required JavaScript library files --> <script language = "JavaScript" src="BasicSupport.js"></script> <script language = "JavaScript" src="EventHandler6.js"></script> </head> <body class="StdC" id="MainApplication"> <button type="button" class="StdC NoSwipe" id="Button1">Try Me Out</button> <button type="button" class="StdC NoSwipe" id="Button2">Alter The 1st Button</button> </body> <script language = "JavaScript" src="NewEventTest.js"></script> </html>
Der Vollständigkeit halber verwende ich auch die folgende einfache CSS-Datei:
/* NewEventTest.css */ /* Define standard display settings classes for a range of HTML elements */ .StdC { color: rgba(255, 255, 255, 1); background-color: rgba(0, 128, 0, 1); font-family: "Book Antiqua", "Times New Roman", "Times", serif; font-size: 100%; font-weight: normal; text-align: center; } .NoSwipe { user-select: none; /* Stops text from being selectable! */ }
Der Testcode lautet wie folgt:
//NewEventTest.js function GlobalVariables() { this.TmpRef1 = null; this.TmpRef2 = null; this.TmpRef3 = null; this.Const1 = null; this.Handler1 = null; this.Handler2 = null; this.Handler3 = null; this.EventOptions = {"passive" : true, "capture" : true }; //End constructor } //Button 1 Initial function function Button1Initial(event) { console.log("Button 1 initial event handler triggered"); //End event handler } function Button1Final(event) { console.log("Button 1 final event handler triggered"); //End event handler } function Button2Handler(event, oldFunc, newFunc) { var funcRef = null; this.removeEventListener("click", oldFunc); this.addEventListener("click", newFunc, GLOBALS.EventOptions); //End event handler } //Application Setup GLOBALS = new GlobalVariables(); GLOBALS.Const1 = new EventHandlerConstants(); GLOBALS.TmpRef1 = document.getElementById("Button1"); GLOBALS.TmpRef2 = MakeEventHandler(Button1Initial, null, []); if (GLOBALS.TmpRef2.status == GLOBALS.Const1.SUCCESS) { GLOBALS.Handler1 = GLOBALS.TmpRef2.actualHandler; GLOBALS.TmpRef1.addEventListener("click", GLOBALS.Handler1, GLOBALS.EventOptions); //End if } GLOBALS.TmpRef1 = MakeEventHandler(Button1Final, null, []); if (GLOBALS.TmpRef1.status == GLOBALS.Const1.SUCCESS) { GLOBALS.Handler3 = GLOBALS.TmpRef1.actualHandler; //End if } GLOBALS.TmpRef1 = document.getElementById("Button2"); GLOBALS.TmpRef2 = document.getElementById("Button1"); GLOBALS.TmpRef3 = Button1Final; GLOBALS.TmpRef4 = MakeEventHandler(Button2Handler, GLOBALS.TmpRef2, [GLOBALS.Handler1, GLOBALS.Handler3]); if (GLOBALS.TmpRef4.status == GLOBALS.Const1.SUCCESS) { GLOBALS.Handler2 = GLOBALS.TmpRef4.actualHandler; GLOBALS.TmpRef1.addEventListener("click", GLOBALS.Handler2, GLOBALS.EventOptions); //End if }
Der durchzuführende Test ist also wie folgt:
[1] Fügen Sie einen Klickereignishandler zu Schaltfläche 1 hinzu.
[2] Testen Sie, ob der Ereignishandler aufgerufen wird, wenn ich auf die Schaltfläche klicke.
[3] Wenn dieser Test bestanden ist, klicken Sie auf Schaltfläche 2 und rufen Sie den daran angehängten Ereignishandler auf, der den alten Ereignishandler entfernt, der an Schaltfläche 1 angehängt ist, und ihn dann durch einen neuen Ereignishandler ersetzt.
Die Schritte [1] und [2] funktionieren einwandfrei. Der Ereignishandler wird angehängt und aufgerufen, wenn ich auf die Schaltfläche klicke.
Das Problem liegt bei Schritt [3].
Obwohl ich einen Verweis auf die von MakeEventHandler () generierte Funktion speichere, insbesondere um diesen Ereignis-Listener in Schritt [3] zu entfernen, entfernt der Aufruf von removeEventListener () den Ereignis-Listener NICHT. Das anschließende Klicken auf Button # 1 löst BEIDE Ereignis-Listener aus, einschließlich desjenigen, den ich angeblich entfernt habe!
Unnötig zu erwähnen, dass dieses Verhalten ich rätselhaft finde, obwohl ich alles sorgfältig so eingerichtet habe, dass die Funktion, die ich im Aufruf von removeEventListener () angegeben habe, dieselbe Funktion ist, die ich ursprünglich mit addEventListener () hinzugefügt habe - gemäß der gesamten Dokumentation zu diesem Thema I. Ich habe gelesen (einschließlich dieses Threads), dass die Übergabe eines Verweises auf dieselbe Funktion für jeden Aufruf funktionieren sollte , aber eindeutig nicht.
In Schritt [1] lautet die Testausgabe in der Konsole wie erwartet:
Der Code wird erwartungsgemäß auch in Schritt [2] ausgeführt, und eine schrittweise Verfolgung des Codes zeigt, dass der Code tatsächlich wie erwartet ausgeführt wird.
Aber in Schritt [3], während der erste Klick auf Button # 1 das gewünschte Ergebnis liefert:
Was passiert, wenn anschließend auf Schaltfläche 1 geklickt wird, ist Folgendes :
Selbst wenn die ursprünglich an Schaltfläche 1 angehängte Funktion im Speicher verbleibt, weil sie innerhalb eines Abschlusses generiert wurde, sollte sie dennoch von der Ereignis-Listener-Sammlung für das Element getrennt werden. Warum ist es noch verbunden?
Oder bin ich auf einen seltsamen Fehler gestoßen, bei dem Schließungen mit Ereignis-Listenern verwendet wurden, der gemeldet werden muss?
quelle