¿Cómo encontrar detectores de eventos en un nodo DOM al depurar o desde un código JavaScript?

Tengo una página donde algunos oyentes de eventos están adjuntos a los campos de entrada y seleccionan rectángulos. ¿Hay alguna manera de averiguar qué escuchas de eventos están monitoreando un nodo DOM específico y para qué evento?

Los eventos se conectan mediante:

  • Prototype Event.observe ;
  • DOM addEventListener ;
  • Como un atributo de element.onclick .
706
15 янв. Navneet se establece el 15 de enero 2009-01-15 17:19 '09 a las 17:19 2009-01-15 17:19
@ 17 respuestas

Si solo necesita comprobar lo que está sucediendo en la página, puede probar el marcador de eventos visuales .

Actualizar : Evento Visual 2 ,

469
06 авг. Respuesta dada a Andrew Hedges 06 de agosto. 2010-08-06 20:48 '10 a las 8:48 PM 2010-08-06 20:48

Depende de cómo se relacionen los eventos. Para ilustrar, supongamos que tenemos el siguiente controlador de clic:

 var handler = function() { alert('clicked!') }; 

Vamos a adjuntarlo a nuestro elemento utilizando diferentes métodos, algunos de los cuales nos permiten probar y otros no.

Método A) Controlador de evento único

 element.onclick = handler; // inspect alert(element.onclick); // alerts "function() { alert('clicked!') }" 

Método B) controladores de eventos múltiples

 if(element.addEventListener) { // DOM standard element.addEventListener('click', handler, false) } else if(element.attachEvent) { // IE element.attachEvent('onclick', handler) } // cannot inspect element to find handlers 
border=0

Método C): jQuery

 $(element).click(handler); 
  • 1.3.x

     // inspect var clickEvents = $(element).data("events").click; jQuery.each(clickEvents, function(key, value) { alert(value) // alerts "function() { alert('clicked!') }" }) 
  • 1.4.x (almacena el controlador dentro del objeto)

     // inspect var clickEvents = $(element).data("events").click; jQuery.each(clickEvents, function(key, handlerObj) { alert(handlerObj.handler) // alerts "function() { alert('clicked!') }" // also available: handlerObj.type, handlerObj.namespace }) 

(ver jQuery.fn.data y jQuery.data )

Método D): Prototipo (sucio)

 $(element).observe('click', handler); 
  • 1.5.x

     // inspect Event.observers.each(function(item) { if(item[0] == element) { alert(item[2]) // alerts "function() { alert('clicked!') }" } }) 
  • de 1.6 a 1.6.0.3 inclusive (muy difícil aquí)

     // inspect. "_eventId" is for < 1.6.0.3 while // "_prototypeEventID" was introduced in 1.6.0.3 var clickEvents = Event.cache[element._eventId || (element._prototypeEventID || [])[0]].click; clickEvents.each(function(wrapper){ alert(wrapper.handler) // alerts "function() { alert('clicked!') }" }) 
  • 1.6.1 (ligeramente mejor)

     // inspect var clickEvents = element.getStorage().get('prototype_event_registry').get('click'); clickEvents.each(function(wrapper){ alert(wrapper.handler) // alerts "function() { alert('clicked!') }" }) 
346
15 янв. La respuesta se da Crescent Fresh 15 jan. 2009-01-15 18:13 '09 a las 18:13 2009-01-15 18:13

getEventListeners(domElement) Chrome, Firefox, Vivaldi y Safari getEventListeners(domElement) en la consola del desarrollador.

Para la mayoría de los propósitos de depuración, esto puede ser usado.

A continuación, encontrará una muy buena recomendación: https://developers.google.com/chrome-developer-tools/docs/commandline-api#geteventlistenersobject

203
14 мая '13 в 16:40 2013-05-14 16:40 Raghav da la respuesta el 14 de mayo de 2013 a las 4:40 2013-05-14 16:40

WebKit Inspector en los navegadores Chrome o Safari ahora hace esto. Muestra los escuchas de eventos para el elemento DOM cuando lo selecciona en el panel Elementos.

81
17 янв. Ishan da la respuesta el 17 de enero. 2011-01-17 10:39 '11 a las 10:39 2011-01-17 10:39

En JavaScript, puedes enumerar a todos los oyentes de eventos : no es tan difícil; solo necesitas hackear el método prototype de los elementos HTML (antes de agregar oyentes).

 function reportIn(e){ var a = this.lastListenerInfo[this.lastListenerInfo.length-1]; console.log(a) } HTMLAnchorElement.prototype.realAddEventListener = HTMLAnchorElement.prototype.addEventListener; HTMLAnchorElement.prototype.addEventListener = function(a,b,c){ this.realAddEventListener(a,reportIn,c); this.realAddEventListener(a,b,c); if(!this.lastListenerInfo){ this.lastListenerInfo = new Array()}; this.lastListenerInfo.push({a : a, b : b , c : c}); }; 

Ahora cada elemento de enlace ( a ) tendrá una propiedad lastListenerInfo contiene todos sus escuchas. E incluso funciona para eliminar oyentes con funciones anónimas.

61
22 июня '11 в 7:32 2011-06-22 07:32 La respuesta la da Ivan Castellanos el 22 de junio de 2011 a las 7:32 2011-06-22 07:32

(Reescribiendo la respuesta de esta pregunta , ya que es importante aquí).

Al depurar, si solo quieres ver eventos, te recomiendo o ...

  • Evento visual
  • La sección "Elementos" de las herramientas de desarrollo de Chrome: selecciona un elemento y encuentra los "Oyentes de eventos" en la esquina inferior derecha (similar a Firefox).

Si desea usar eventos en su código y usar jQuery hasta la versión 1.8, puede usar:

 $(selector).data("events") 

para conseguir eventos. A partir de la versión 1.8, el uso de .data ("eventos") se interrumpe (consulte este gran código de error ). Puedes usar:

 $._data(element, "events") 

Otro ejemplo: escriba todos los eventos de clic en un enlace específico a la consola:

 var $myLink = $('a.myClass'); console.log($._data($myLink[0], "events").click); 

(vea http://jsfiddle.net/HmsQC/ para un ejemplo de trabajo)

Desafortunadamente, no se recomienda el uso de $ ._ data , excepto para la depuración, ya que es una estructura interna de jQuery y puede cambiarse en futuras versiones. Desafortunadamente, no conozco otras formas simples de acceder a los eventos.

38
22 окт. Lucas se publica el 22 de octubre 2012-10-22 22:04 '12 a las 10:04 pm 2012-10-22 22:04

Utilice getEventListeners en Google Chrome :

 getEventListeners(document.getElementByID('btnlogin')); getEventListeners($('#btnlogin')); 
26
19 марта '14 в 12:30 2014-03-19 12:30 Pranay Soni da la respuesta el 19 de marzo de 2014 a las 12:30 2014-03-19 12:30

1: Prototype.observe utiliza Element.addEventListener (ver código fuente )

2: Puede anular Element.addEventListener para recordar los escuchas agregados (la propiedad conveniente EventListenerList ha eliminado de la propuesta de especificación de DOM3). Ejecute este código antes de adjuntar cualquier evento:

 (function() { Element.prototype._addEventListener = Element.prototype.addEventListener; Element.prototype.addEventListener = function(a,b,c) { this._addEventListener(a,b,c); if(!this.eventListenerList) this.eventListenerList = {}; if(!this.eventListenerList[a]) this.eventListenerList[a] = []; this.eventListenerList[a].push(b); }; })(); 

Lea todos los eventos:

 var clicks = someElement.eventListenerList.click; if(clicks) clicks.forEach(function(f) { alert("I listen to this function: "+f.toString()); }); 

Y no se olvide de anular Element.removeEventListener para eliminar el evento de la Element.eventListenerList personalizada.

3: La propiedad Element.onclick requiere atención especial:

 if(someElement.onclick) alert("I also listen tho this: "+someElement.onclick.toString()); 

4: no olvide el atributo Element.onclick del contenido: estas son dos cosas diferentes:

 someElement.onclick = someHandler; // IDL attribute someElement.setAttribute("onclick","otherHandler(event)"); // content attribute 

Entonces, también necesitas procesar:

 var click = someElement.getAttribute("onclick"); if(click) alert("I even listen to this: "+click); 

La etiqueta de folleto de eventos visuales (que se menciona en la respuesta más popular) solo roba el caché del controlador de biblioteca de usuario:

Resulta que no hay un método estándar provisto por la interfaz DOM recomendada por el W3C para averiguar qué escuchas de eventos están vinculadas a un elemento específico. Si bien puede parecer una supervisión, se sugirió incluir una propiedad llamada eventListenerList antes del nivel 3 de la especificación de DOM, pero desafortunadamente se eliminó en los borradores posteriores. Por lo tanto, nos vemos obligados a mirar las bibliotecas de JavaScript separadas que normalmente se mantienen en la memoria caché de los eventos conectados (para que se puedan eliminar más tarde y se realicen otras abstracciones útiles).

Por lo tanto, para que el Evento Visual muestre eventos, debe poder analizar la información de eventos de la biblioteca de Javascript.

Los elementos primordiales pueden ser cuestionables (es decir, porque hay algunas funciones específicas de DOM, como las colecciones en vivo que no se pueden codificar en JS), pero inicialmente proporciona compatibilidad con eventListenerList, y funciona en Chrome, Firefox y Opera ( no funcionan en IE7).

22
03 апр. Responder a Jan Turoň 03 de abril 2014-04-03 18:08 14 a las 18:08 2014-04-03 18:08

Puede envolver sus propios métodos DOM para controlar a los oyentes de eventos colocándolos en la parte superior de su <head> :

 <script> (function(w){ var originalAdd = w.addEventListener; w.addEventListener = function(){ // add your own stuff here to debug return originalAdd.apply(this, arguments); }; var originalRemove = w.removeEventListener; w.removeEventListener = function(){ // add your own stuff here to debug return originalRemove.apply(this, arguments); }; })(window); </script> 

H / T @ les2

21
06 нояб. La respuesta es dada por Jon z 06 de noviembre 2015-11-06 20:49 '15 a las 8:49 pm 2015-11-06 20:49

Ahora las herramientas para desarrolladores de Firefox lo hacen. Los eventos se muestran presionando el botón "ev" a la derecha de la pantalla de cada elemento, incluidos los eventos jQuery y DOM .

2019

16
14 янв. la respuesta es dada por simonzack 14 jan. 2015-01-14 18:33 '15 a las 18:33 2015-01-14 18:33

Si tiene Firebug , puede usar console.dir(object or array) para imprimir un hermoso árbol en el registro de la consola de cualquier escáner, matriz u objeto de JavaScript.

Prueba

 console.dir(clickEvents); 

o

 console.dir(window); 
12
08 янв. Responder Michael Butler 08 de enero 2010-01-08 01:52 '10 a la 1:52 2010-01-08 01:52

Opera 12 (no es el último motor de Chrome Webkit) Dragonfly tiene esto por un tiempo y se muestra claramente en la estructura DOM. En mi opinión, este es un excelente depurador, y esta es la única razón por la que todavía uso la versión basada en Opera 12 (no hay una versión v13, Falta la libélula basada en Webkit v14 y v15)

2019

7
28 нояб. La respuesta es dada Daniel Sokolowski 28 de noviembre. 2013-11-28 19:30 '13 a las 19:30 2013-11-28 19:30

Solución totalmente funcional basada en la respuesta de Jan Turon : se comporta como getEventListeners() desde la consola:

(Hay un pequeño error con los duplicados. En cualquier caso, esto no se rompe mucho).

 (function() { Element.prototype._addEventListener = Element.prototype.addEventListener; Element.prototype.addEventListener = function(a,b,c) { if(c==undefined) c=false; this._addEventListener(a,b,c); if(!this.eventListenerList) this.eventListenerList = {}; if(!this.eventListenerList[a]) this.eventListenerList[a] = []; //this.removeEventListener(a,b,c); // TODO - handle duplicates.. this.eventListenerList[a].push({listener:b,useCapture:c}); }; Element.prototype.getEventListeners = function(a){ if(!this.eventListenerList) this.eventListenerList = {}; if(a==undefined) return this.eventListenerList; return this.eventListenerList[a]; }; Element.prototype.clearEventListeners = function(a){ if(!this.eventListenerList) this.eventListenerList = {}; if(a==undefined){ for(var x in (this.getEventListeners())) this.clearEventListeners(x); return; } var el = this.getEventListeners(a); if(el==undefined) return; for(var i = el.length - 1; i >= 0; --i) { var ev = el[i]; this.removeEventListener(a, ev.listener, ev.useCapture); } }; Element.prototype._removeEventListener = Element.prototype.removeEventListener; Element.prototype.removeEventListener = function(a,b,c) { if(c==undefined) c=false; this._removeEventListener(a,b,c); if(!this.eventListenerList) this.eventListenerList = {}; if(!this.eventListenerList[a]) this.eventListenerList[a] = []; // Find the event in the list for(var i=0;i<this.eventListenerList[a].length;i++){ if(this.eventListenerList[a][i].listener==b, this.eventListenerList[a][i].useCapture==c){ // Hmm.. this.eventListenerList[a].splice(i, 1); break; } } if(this.eventListenerList[a].length==0) delete this.eventListenerList[a]; }; })(); 

Uso:

someElement.getEventListeners([name]) : devuelve una lista de escuchas de eventos; si se establece el nombre, devuelve una matriz de escuchas para este evento.

someElement.clearEventListeners([name]) : elimina todos los escuchas de eventos, si el nombre está establecido, solo quita los escuchas para este evento

6
27 июня '15 в 13:47 2015-06-27 13:47 la respuesta se da n00b 27 de junio, '15 a 13:47 2015-06-27 13:47

Prototipo 1.7.1.

 function get_element_registry(element) { var cache = Event.cache; if(element === window) return 0; if(typeof element._prototypeUID === 'undefined') { element._prototypeUID = Element.Storage.UID++; } var uid = element._prototypeUID; if(!cache[uid]) cache[uid] = {element: element}; return cache[uid]; } 
4
17 янв. Respuesta de Ronald Lewis Berner II 17 de enero. 2013-01-17 20:28 '13 a las 20:28 2013-01-17 20:28

Estoy intentando hacer esto en jQuery 2.1, y usando el método " $().click() -> $(element).data("events").click; " no funciona.

Me di cuenta de que en mi caso solo funcionan las funciones $ ._ data ():

 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <body> </body> 
2
19 мая '15 в 11:33 2015-05-19 11:33 La respuesta la da Joel Barba el 19 de mayo de 2015 a las 11:33 2015-05-19 11:33
28 февр. Respuesta de T.Todua el 28 de febrero 2017-02-28 18:13 '17 a las 18:13 2017-02-28 18:13

Recientemente trabajé con eventos y quería ver / controlar todos los eventos en la página. Habiendo considerado posibles soluciones, decidí seguir mi propio camino y crear mi propio sistema de monitoreo de eventos. Entonces, hice tres cosas.

Primero, necesito un contenedor para todos los detectores de eventos en la página: el objeto EventListeners . Tiene tres métodos útiles: add() , remove() y get() .

Luego, creé un objeto EventListener para almacenar la información necesaria para el evento, es decir, el target , el type , la callback , las options , el uso de useCapture , wantsUntrusted y agregué un método remove() para eliminar al oyente.

Finalmente, extendí mi propio addEventListener() y removeEventListener() para que funcionen con los objetos EventListener creados ( EventListener y EventListeners ).

Aplicación:

 var bodyClickEvent = document.body.addEventListener("click", function () { console.log("body click"); }); // bodyClickEvent.remove(); 

addEventListener() crea un objeto EventListener , lo agrega a EventListeners y devuelve un objeto EventListener , por lo que puede eliminarlo más tarde.

EventListeners.get() se puede usar para ver oyentes en una página. Acepta un EventTarget o cadena (tipo de evento).

 // EventListeners.get(document.body); // EventListeners.get("click"); 

demostración

Digamos que queremos conocer a cada oyente de eventos en esta página actual. Podemos hacer esto (suponiendo que utilice la extensión del administrador de scripts, Tampermonkey en este caso). El siguiente script hace lo siguiente:

 // ==UserScript== // @name New Userscript // @namespace http://tampermonkey.net/ // @version 0.1 // @description try to take over the world! // @author You // @include https://stackoverflow.com/* // @grant none // ==/UserScript== (function() { fetch("https://raw.githubusercontent.com/akinuri/js-lib/master/EventListener.js") .then(function (response) { return response.text(); }) .then(function (text) { eval(text); window.EventListeners = EventListeners; }); })(window); 

Y cuando enumeramos a todos los oyentes, dice que hay 299 oyentes de eventos. Parece que hay varios duplicados, pero no sé si realmente son duplicados. No todos los tipos de eventos están duplicados, por lo que todos estos "duplicados" pueden ser un oyente individual.

2019

28 июня '18 в 12:21 2018-06-28 12:21 la respuesta se da akinuri el 28 de junio de 18 a las 12:21 pm 2018-06-28 12:21

Otras preguntas sobre tags o Haz una pregunta