Solo pregunta: ¿Hay alguna forma de eliminar completamente todos los eventos de un objeto, por ejemplo, un div?
EDITAR: Estoy agregando por div.addEventListener('click',eventReturner(),false);
evento.
function eventReturner() {
return function() {
dosomething();
};
}
EDIT2: Encontré una manera, que funciona, pero no es posible de usar para mi caso:
var returnedFunction;
function addit() {
var div = document.getElementById('div');
returnedFunction = eventReturner();
div.addEventListener('click',returnedFunction,false); //You HAVE to take here a var and not the direct call to eventReturner(), because the function address must be the same, and it would change, if the function was called again.
}
function removeit() {
var div = document.getElementById('div');
div.removeEventListener('click',returnedFunction,false);
}
javascript
events
dom
Florian Müller
fuente
fuente
div.onclick=null
. Por supuesto, no debe usaraddEventListener
en este caso por completo, ya que agregará un oyente diferente al que está enonclick
.Respuestas:
No estoy seguro de a qué te refieres con eliminar todos los eventos . ¿Eliminar todos los controladores para un tipo específico de evento o todos los controladores de eventos para un tipo?
Eliminar todos los controladores de eventos
Si desea eliminar todos los controladores de eventos (de cualquier tipo), puede clonar el elemento y reemplazarlo con su clon:
var clone = element.cloneNode(true);
Nota: Esto conservará los atributos y los hijos, pero no conservará ningún cambio en las propiedades del DOM.
Eliminar controladores de eventos "anónimos" de un tipo específico
La otra forma es usarlo,
removeEventListener()
pero supongo que ya lo intentaste y no funcionó. Aquí está el truco :Básicamente, está pasando una función anónima a
addEventListener
comoeventReturner
devuelve una función.Tienes dos posibilidades para solucionar esto:
No use una función que devuelva una función. Utilice la función directamente:
function handler() { dosomething(); } div.addEventListener('click',handler,false);
Cree un contenedor para
addEventListener
que almacene una referencia a la función devuelta y cree unaremoveAllEvents
función extraña :var _eventHandlers = {}; // somewhere global const addListener = (node, event, handler, capture = false) => { if (!(event in _eventHandlers)) { _eventHandlers[event] = [] } // here we track the events and their nodes (note that we cannot // use node as Object keys, as they'd get coerced into a string _eventHandlers[event].push({ node: node, handler: handler, capture: capture }) node.addEventListener(event, handler, capture) } const removeAllListeners = (targetNode, event) => { // remove listeners from the matching nodes _eventHandlers[event] .filter(({ node }) => node === targetNode) .forEach(({ node, handler, capture }) => node.removeEventListener(event, handler, capture)) // update _eventHandlers global _eventHandlers[event] = _eventHandlers[event].filter( ({ node }) => node !== targetNode, ) }
Y luego podrías usarlo con:
addListener(div, 'click', eventReturner(), false) // and later removeAllListeners(div, 'click')
MANIFESTACIÓN
Nota: Si su código se ejecuta durante mucho tiempo y está creando y eliminando muchos elementos, deberá asegurarse de eliminar los elementos contenidos en
_eventHandlers
cuando los destruya.fuente
element.parentNode
podría ser nulo. Probablemente debería poner una marca si alrededor del código anterior.Esto eliminará todos los oyentes de los niños, pero será lento para páginas grandes. Brutalmente simple de escribir.
fuente
document.querySelector('body').outerHTML = document.querySelector('body').outerHTML
trabajó para mi.document.querySelector('body').outerHTML
usted puede simplemente escribirdocument.body.outerHTML
Utilice la propia función del detector de eventos
remove()
. Por ejemplo:getEventListeners().click.forEach((e)=>{e.remove()})
fuente
getEventListeners
solo está disponible en las herramientas de desarrollo de WebKit y en FireBug. No es algo que puedas simplemente llamar en tu código.getEventListeners()
. ejemplo:getEventListeners(document)
ogetEventListeners(document.querySelector('.someclass'))
getEventListeners(document).click.forEach((e)=>{e.remove()})
produce este error:VM214:1 Uncaught TypeError: e.remove is not a function
Como dice corwin.amber, existen diferencias entre Webkit y otros.
En Chrome:
getEventListeners(document);
Lo que le da un objeto con todos los oyentes de eventos existentes:
Object click: Array[1] closePopups: Array[1] keyup: Array[1] mouseout: Array[1] mouseover: Array[1] ...
Desde aquí puede llegar al oyente que desea eliminar:
getEventListeners(document).copy[0].remove();
Entonces, todos los oyentes de eventos:
for(var eventType in getEventListeners(document)) { getEventListeners(document)[eventType].forEach( function(o) { o.remove(); } ) }
En Firefox
Es un poco diferente porque usa un contenedor de escucha que no contiene función de eliminación. Tienes que obtener el oyente que deseas eliminar:
document.removeEventListener("copy", getEventListeners(document).copy[0].listener)
Todos los oyentes de eventos:
for(var eventType in getEventListeners(document)) { getEventListeners(document)[eventType].forEach( function(o) { document.removeEventListener(eventType, o.listener) } ) }
Me encontré con esta publicación tratando de deshabilitar la molesta protección contra copias de un sitio web de noticias.
¡Disfrutar!
fuente
getEventListeners
no está definido?Puede agregar una función de gancho para interceptar todas las llamadas
addEventHandler
. El gancho empujará al manejador a una lista que se puede usar para la limpieza. Por ejemplo,if (EventTarget.prototype.original_addEventListener == null) { EventTarget.prototype.original_addEventListener = EventTarget.prototype.addEventListener; function addEventListener_hook(typ, fn, opt) { console.log('--- add event listener',this.nodeName,typ); this.all_handlers = this.all_handlers || []; this.all_handlers.push({typ,fn,opt}); this.original_addEventListener(typ, fn, opt); } EventTarget.prototype.addEventListener = addEventListener_hook; }
Debe insertar este código cerca de la parte superior de su página web principal (por ejemplo
index.html
). Durante la limpieza, puede recorrer all_handlers y llamar a removeEventHandler para cada uno. No se preocupe por llamar a removeEventHandler varias veces con la misma función. Es inofensivo.Por ejemplo,
function cleanup(elem) { for (let t in elem) if (t.startsWith('on') && elem[t] != null) { elem[t] = null; console.log('cleanup removed listener from '+elem.nodeName,t); } for (let t of elem.all_handlers || []) { elem.removeEventListener(t.typ, t.fn, t.opt); console.log('cleanup removed listener from '+elem.nodeName,t.typ); } }
Nota: para IE, use Element en lugar de EventTarget, y cambie => para funcionar, y varias otras cosas.
fuente
Para completar las respuestas, aquí hay ejemplos del mundo real de cómo eliminar eventos cuando visita sitios web y no tiene control sobre el código HTML y JavaScript generado.
Algunos sitios web molestos le impiden copiar y pegar nombres de usuario en formularios de inicio de sesión, lo que podría omitirse fácilmente si el
onpaste
evento se agrega con elonpaste="return false"
atributo HTML. En este caso, solo necesitamos hacer clic derecho en el campo de entrada, seleccionar "Inspeccionar elemento" en un navegador como Firefox y eliminar el atributo HTML.Sin embargo, si el evento se agregó a través de JavaScript de esta manera:
document.getElementById("lyca_login_mobile_no").onpaste = function(){return false};
Tendremos que eliminar el evento a través de JavaScript también:
document.getElementById("lyca_login_mobile_no").onpaste = null;
En mi ejemplo, utilicé el ID "lyca_login_mobile_no" ya que era el ID de entrada de texto utilizado por el sitio web que estaba visitando.
Otra forma de eliminar el evento (que también eliminará todos los eventos) es eliminar el nodo y crear uno nuevo, como tenemos que hacer si
addEventListener
se usó para agregar eventos usando una función anónima que no podemos eliminar conremoveEventListener
. Esto también se puede hacer a través de la consola del navegador inspeccionando un elemento, copiando el código HTML, eliminando el código HTML y luego pegando el código HTML en el mismo lugar.También se puede hacer más rápido y automatizado a través de JavaScript:
var oldNode = document.getElementById("lyca_login_mobile_no"); var newNode = oldNode.cloneNode(true); oldNode.parentNode.insertBefore(newNode, oldNode); oldNode.parentNode.removeChild(oldNode);
Actualización: si la aplicación web se crea con un marco de JavaScript como Angular, parece que las soluciones anteriores no funcionan o no funcionan. Otra solución para permitir pegar sería establecer el valor a través de JavaScript:
document.getElementById("lyca_login_mobile_no").value = "username";
Por el momento, no sé si hay una manera de eliminar todos los eventos de validación y restricción de formularios sin romper una aplicación escrita completamente en JavaScript como Angular.
fuente
angular tiene un polyfill para este problema, puede verificar. No entendí mucho, pero tal vez pueda ayudar.
const REMOVE_ALL_LISTENERS_EVENT_LISTENER = 'removeAllListeners';
proto[REMOVE_ALL_LISTENERS_EVENT_LISTENER] = function () { const target = this || _global; const eventName = arguments[0]; if (!eventName) { const keys = Object.keys(target); for (let i = 0; i < keys.length; i++) { const prop = keys[i]; const match = EVENT_NAME_SYMBOL_REGX.exec(prop); let evtName = match && match[1]; // in nodejs EventEmitter, removeListener event is // used for monitoring the removeListener call, // so just keep removeListener eventListener until // all other eventListeners are removed if (evtName && evtName !== 'removeListener') { this[REMOVE_ALL_LISTENERS_EVENT_LISTENER].call(this, evtName); } } // remove removeListener listener finally this[REMOVE_ALL_LISTENERS_EVENT_LISTENER].call(this, 'removeListener'); } else { const symbolEventNames = zoneSymbolEventNames$1[eventName]; if (symbolEventNames) { const symbolEventName = symbolEventNames[FALSE_STR]; const symbolCaptureEventName = symbolEventNames[TRUE_STR]; const tasks = target[symbolEventName]; const captureTasks = target[symbolCaptureEventName]; if (tasks) { const removeTasks = tasks.slice(); for (let i = 0; i < removeTasks.length; i++) { const task = removeTasks[i]; let delegate = task.originalDelegate ? task.originalDelegate : task.callback; this[REMOVE_EVENT_LISTENER].call(this, eventName, delegate, task.options); } } if (captureTasks) { const removeTasks = captureTasks.slice(); for (let i = 0; i < removeTasks.length; i++) { const task = removeTasks[i]; let delegate = task.originalDelegate ? task.originalDelegate : task.callback; this[REMOVE_EVENT_LISTENER].call(this, eventName, delegate, task.options); } } } } if (returnTarget) { return this; } };
....
fuente
EVENT_NAME_SYMBOL_REGX
supone que viene?Puede agregar una función auxiliar que borre el detector de eventos, por ejemplo
function clearEventListener(element) { const clonedElement = element.cloneNode(true); element.replaceWith(clonedElement); return clonedElement; }
simplemente pase el elemento a la función y eso es todo ...
fuente
var div = getElementsByTagName('div')[0]; /* first div found; you can use getElementById for more specific element */ div.onclick = null; // OR: div.onclick = function(){};
//editar
No sabía qué método estás usando para adjuntar eventos. Porque
addEventListener
puedes usar esto:div.removeEventListener('click',functionName,false); // functionName is the name of your callback function
mas detalles
fuente
div.onClick = something
, establece otro evento onClick, pero el anterior permanece, así que tengo el anterior y uno, por ejemplo, nulo ...addEventListener()
.addEventListener()
...Puede ser que el navegador lo haga por usted si hace algo como:
Copie el
div
y sus atributos e insértelo antes del anterior, luego mueva el contenido del antiguo al nuevo y elimine el antiguo.fuente
Eliminando todos los eventos en
document
:Un trazador de líneas:
for (key in getEventListeners(document)) { getEventListeners(document)[key].forEach(function(c) { c.remove() }) }
Bonita versión:
for (key in getEventListeners(document)) { getEventListeners(document)[key].forEach(function(c) { c.remove() }) }
fuente
Solo Chrome
Como intento eliminar un EventListener dentro de una prueba de transportador y no tengo acceso al Listener en la prueba, lo siguiente funciona para eliminar todos los oyentes de eventos de un solo tipo:
function(eventType){ getEventListeners(window).[eventType].forEach( function(e){ window.removeEventListener(eventType, e.listener) } ); }
Espero que esto ayude a alguien, ya que la respuesta anterior estaba usando el método "eliminar" que desde entonces ya no funciona.
fuente
Un método es agregar un nuevo detector de eventos que llame a e.stopImmediatePropagation ().
fuente