not change javascript events addeventlistener

change - Javascript removeEventListener no funciona



addeventlistener typescript (7)

Tengo el siguiente código para agregar eventListener

area.addEventListener(''click'',function(event) { app.addSpot(event.clientX,event.clientY); app.addFlag = 1; },true);

Está funcionando correctamente como se esperaba. Más tarde en otra función intenté eliminar el detector de eventos usando el siguiente código

area.removeEventListener(''click'',function(event) { app.addSpot(event.clientX,event.clientY); app.addFlag = 1; },true);

Pero el oyente par no se elimina ... ¿Por qué está pasando? ¿Hay algún problema con mi removeEventListener ()? Nota: Aquí el área es algo así como document.getElementById (''myId'')


Encuentro que para el objeto de Windows, se requiere el último parámetro "verdadero". La eliminación no funciona si no hay indicador de captura.


Está creando dos funciones diferentes en ambas llamadas. Entonces, la segunda función no se relaciona de ninguna manera con la primera y el motor puede eliminar la función. Use un identificador común para la función en su lugar.

var handler = function(event) { app.addSpot(event.clientX,event.clientY); app.addFlag = 1; }; area.addEventListener(''click'', handler,true);

más tarde, puede quitar el controlador llamando

area.removeEventListener(''click'', handler,true);


Esto se debe a que dos funciones anónimas son funciones completamente diferentes. Su argumento removeEventListener no es una referencia al objeto de función que se adjuntó anteriormente.

function foo(event) { app.addSpot(event.clientX,event.clientY); app.addFlag = 1; } area.addEventListener(''click'',foo,true); area.removeEventListener(''click'',foo,true);


He encontrado un problema con removeEventListener () que necesita explicación.

Quería poder pasar parámetros a los oyentes de eventos, así que escribí una función para generar el oyente de eventos, que a su vez devuelve una segunda función, que llama a mi oyente de eventos previsto como una devolución de llamada.

El archivo completo de la biblioteca es el siguiente:

//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 }

Luego escribí una página de prueba rápida para ver si funcionaba como estaba previsto, y me permitió agregar Y eliminar manejadores de eventos a voluntad.

La página de prueba HTML es la siguiente:

<!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>

Para completar, también uso el siguiente archivo CSS simple:

/* 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! */ }

El código de prueba es el siguiente:

//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 }

Por lo tanto, la prueba que se realizará es la siguiente:

[1] Adjunte un controlador de evento click al Botón # 1;

[2] Prueba para ver si se invoca al controlador de eventos cuando hago clic en el botón;

[3] Una vez que se aprueba la prueba, haga clic en el Botón n.º 2 e invoque el controlador de eventos adjunto, que elimina el antiguo controlador de eventos adjunto al Botón n.º 1 y luego lo reemplaza con un nuevo controlador de eventos.

Los pasos [1] y [2] funcionan bien. El controlador de eventos se adjunta e invoca cada vez que hago clic en el botón.

El problema es con el Paso [3].

Aunque guardo una referencia a la función generada por MakeEventHandler (), específicamente con el propósito de eliminar ese detector de eventos en el Paso [3], la llamada a removeEventListener () NO elimina el detector de eventos. Al hacer clic en el botón n. ° 1, se apagan AMBOS detectores de eventos, incluido el que supuestamente eliminé.

Huelga decir que este comportamiento me resulta desconcertante, a pesar de configurar cuidadosamente todo para que la función que especifico en la llamada a removeEventListener () es la misma función que agregué inicialmente con addEventListener () - de acuerdo con toda la documentación sobre el tema I He leído (incluyendo este hilo), pasar una referencia a la misma función para cada llamada debería funcionar, pero claramente no.

En el Paso [1], la salida de prueba en la consola se lee, como se esperaba:

Botón 1 manejador de evento inicial disparado

El código también se ejecuta, como se esperaba, en el Paso [2], y un rastro paso a paso del código revela que, de hecho, el código se ejecuta como se esperaba.

Pero en el paso [3], mientras que el primer clic en el botón n. ° 1 produce el resultado deseado:

Se desencadena el controlador de evento final del botón 1

lo que sucede cuando se hace clic en el botón n. ° 1 posteriormente es esto:

Botón 1 manejador de evento inicial disparado Botón 1 manejador de evento final disparado

Seguramente, incluso si la función inicialmente asociada al botón n. ° 1 persiste en la memoria, ya que se generó dentro de un cierre, aún debería separarse de la colección del detector de eventos para el elemento. ¿Por qué todavía está conectado?

¿O me he encontrado con algún error raro que implica el uso de cierres con oyentes de eventos, que necesita ser informado?


Para eliminarlo, almacene la función en una variable o simplemente use una función con nombre y pase esa función a la llamada removeEventListener :

function areaClicked(event) { app.addSpot(event.clientX, event.clientY); app.addFlag = 1; } area.addEventListener(''click'', areaClicked, true); // ... area.removeEventListener(''click'', areaClicked, true);


Si desea pasar variables locales a la función llamada por el detector de eventos, puede definir la función dentro de la función (para obtener las variables locales) y pasar el nombre de la función en la función misma. Por ejemplo, comencemos dentro de la función que agrega el detector de eventos con la aplicación como una variable local. Debería escribir una función dentro de esta función como,

function yourFunction () { var app; function waitListen () { waitExecute(app, waitListen); } area.addEventListener(''click'', waitListen, true); }

Luego tiene lo que necesita para eliminarlo cuando se invoca waitExecute.

function waitExecute (app, waitListen) { ... // other code area.removeEventListener(''click'', waitListen, true); }


defina su controlador de eventos primero,

y entonces

area.addEventListener(''click'',handler); area.removeEventListener(''click'',handler);