Digamos que agregamos un oyente uniforme a un botón como este
function handler(){ alert(0) } btn.addEventListener("click", handler) ahora, si queremos eliminar el detector de eventos, simplemente podemos hacer: btn.removeEventListener("click", handler)
pero qué pasa si no tenemos acceso a la función del controlador. por ejemplo, alguna biblioteca de terceros adjunta un detector de eventos a un elemento y quiero eliminarlo. ¿Cómo podemos hacerlo?
Como está escrito en los comentarios, no puede eliminar un detector de eventos sin tener la referencia de devolución de llamada a menos que vuelva a crear/clonar ese elemento, lo que puede ser problemático a veces y tampoco parece ser una buena práctica o particularmente eficaz ( Alerta de spoiler - Ninguno de las posibles soluciones puede considerarse una buena práctica porque su situación no es la ideal desde el principio).
Como alternativa, puedes probar algo como esto:
element.addEventListener('click', (e) => { e.stopImmediatePropagation(); e.stopPropagation(); }, true); Lo más probable es que su biblioteca de terceros esté escuchando el evento en la fase bubbling . Si es así, hacer esto en la fase de capture (consulte el tercer argumento de addEventListener ) evitará que se disparen los oyentes de terceros.
Tenga en cuenta que esto interrumpirá la propagación de eventos en la fase de capture . Esto significa que cualquier oyente establecido en la fase bubbling para ese evento, activado en ese elemento o cualquiera de sus elementos secundarios no se activará. Además, los oyentes restantes en la fase de capture tampoco se dispararán.
Aprovechando la Naturaleza del Evento
Si agrega el detector de eventos anterior antes de que su biblioteca de terceros agregue sus propios detectores de eventos, puede estar "más seguro" de que el suyo se activará primero.
Tenga en cuenta que los oyentes de la fase de capture SIEMPRE se activarán antes que los oyentes de la fase bubbling y SIEMPRE se respetará el orden DOM de ese elemento.
Lo que es un poco impredecible es el orden de ejecución de varios oyentes para el mismo evento en la misma fase y en el mismo elemento de destino. Consulte Orden de eventos .
Dicho esto, si agrega el oyente anterior al PADRE de su elemento interesado, puede estar 99% seguro de que su oyente de biblioteca de terceros no se ejecutará y esto tiene un impacto de rendimiento casi nulo. (El 1% restante es para el caso en que la biblioteca de alguna manera agregue un detector de eventos en la fase de capture y en un ancestro anterior al suyo, que también podría ser el objeto de la window ).
Si aún desea activar oyentes para el elemento principal, puede filtrar los casos utilizando la propiedad event.target .
Algo como:
parent.addEventListener('click', (e) => { if (element.contains(e.target)) { e.stopPropagation(); } }, true);Nota final
Me tomé el tiempo de escribir todo esto más como un ejemplo didáctico sobre eventos DOM que como una solución de trabajo real. Esto se debe a que cualquier posible solución que se me ocurra en este momento tendrá algún tipo de inconveniente, problema o limitación (rendimiento, depuración, imprevisibilidad, etc.)
Una forma más sencilla es clonar el nodo y sus elementos secundarios para eliminar todos los oyentes.
function recreateNode(el, withChildren) { if (withChildren) { el.parentNode.replaceChild(el.cloneNode(true), el); } else { var newEl = el.cloneNode(false); while (el.hasChildNodes()) newEl.appendChild(el.firstChild); el.parentNode.replaceChild(newEl, el); } } Aquí withChildren: true también reemplazará todos los elementos anidados. Con su pregunta, no necesita averiguar la función de referencia.
Esto es lo que probé (aunque no funcionó)
function removeEListener(element, event){ let listeners = getEventListeners(element)[event] try{ listeners.forEach(listener => { listener.remove() element.removeEventListener(event, listener.listener, listener.useCapture) }) }catch(e){ console.log(e) } } removeEListener(document.querySelector(".btn"), 'click')