¿Cómo encontrar escuchadores de eventos en un nodo del DOM cuando se depura o desde el código JavaScript?

Tengo una página en la que algunos escuchadores de eventos están adjuntos a cuadros de entrada y cuadros de selección. ¿Hay alguna manera de averiguar qué oyentes de eventos están observando un nodo DOM en particular y para qué evento?

Los eventos se adjuntan utilizando:

  1. Prototype's Event.observe;
  2. DOM's addEventListener;
  3. Como atributo del elemento element.onclick.
Solución

Si sólo necesita inspeccionar lo que ocurre en una página, puede probar el bookmarklet Evento visual.

Actualización: Evento visual 2 disponible;

Comentarios (13)

Depende de cómo se adjunten 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 que permiten la inspección y otros que no.

Método A) manejador de evento único

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

Método B) múltiples manejadores de eventos

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

Método C): jQuery

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

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

     // inspeccionar
     var clickEvents = $(element).data("events").click;
     jQuery.each(clickEvents, function(key, handlerObj) {
         alert(handlerObj.handler) // alerts "function() { alert('clicked!') }"
         // también disponible: handlerObj.type, handlerObj.namespace
     })

(Ver jQuery.fn.data y jQuery.data)

Método D): Prototipo (desordenado)

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

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

     // inspeccionar. "_eventId" es para < 1.6.0.3 mientras
     // "_prototypeEventID" se introdujo en 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 (un poco mejor)

     // inspeccionar
     var clickEvents = element.getStorage().get('prototype_event_registry').get('click');
     clickEvents.each(function(wrapper){
         alert(wrapper.handler) // alerts "function() { alert('clicked!') }"
     })
Comentarios (8)

Si tienes Firebug, puedes usar console.dir(object or array) para imprimir un bonito árbol en el registro de la consola de cualquier escalar, array u objeto de JavaScript.

Pruebe:

console.dir(clickEvents);

o

console.dir(window);
Comentarios (1)