Como encontrar ouvintes de eventos em um nó DOM ao depurar ou a partir do código JavaScript?

Eu tenho uma página onde alguns ouvintes de eventos estão anexados a caixas de entrada e caixas de seleção. Existe uma maneira de descobrir quais os ouvintes de eventos que estão observando um determinado nó DOM e para qual evento?

Os eventos são anexados usando:

  1. Protótipo's `Evento.observar';
  2. DOM's addEventListener;
  3. Como atributo do elemento `element.onclick'.
Solução

Se você só precisa inspecionar o que's está acontecendo em uma página, você pode tentar o Evento Visual bookmarklet.

*Atualização***: Evento Visual 2 disponível;

Comentários (13)

Depende de como os eventos estão ligados. Para ilustração presuma que temos o seguinte manipulador de cliques:

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

Nós'vamos ligá-lo ao nosso elemento usando métodos diferentes, alguns que permitem a inspecção e outros que não't.

Método A) manipulador de um único evento

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

Método B) manipuladores de múltiplos 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

     // inspecionar
     var clickEvents = $(element).data("events").click;
     jQuery.each(clickEvents, function(key, value) {
         alert(value) // alerts "function() { alert('clicked!') }"
     })
  • 1.4.x (armazena o manipulador dentro de um objeto)

     // inspecionar
     var clickEvents = $(element).data("events").click;
     jQuery.each(clickEvents, function(key, handlerObj) {
         alert(handlerObj.handler) // alerts "function() { alert('clicked!') }"
         // também disponível: handlerObj.type, handlerObj.namespace
     })

(Veja jQuery.fn.data e jQuery.data)

Método D): Protótipo (confuso)

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

     // inspecionar
     Event.observers.each(function(item) {
         if(item[0] == elemento) {
             alert(item[2]) // alerts "function() { alert('clicked!') }"
         }
     })
  • 1.6 a 1.6.0.3, inclusive (ficou muito difícil aqui)

     // inspect. "_eventId" é para < 1.6.0.3 enquanto
     // "_prototypeEventID" foi introduzido em 1.6.0.3
     var clickEvents = Event.cache[element._eventId ||| (element._prototypeEventID || [])[0]].click;
     clickEvents.each(function(wrapper){
         alert(wrapper.handler) // alertas "function() { alert('clicked!') }"
     })
  • 1.6.1 (um pouco melhor)

     // inspecionar
     var clickEvents = element.getStorage().get('prototype_event_registry').get('click');
     clickEvents.each(function(wrapper){
         alert(wrapper.handler) // alertas "function() { alert('clicked!') }"
     })
Comentários (8)

Se você tem Firebug, você pode utilizar console.dir(object or array) para imprimir uma bela árvore no log do console de qualquer escalar, array ou objeto JavaScript.

Tente:

console.dir(clickEvents);

ou

console.dir(window);
Comentários (1)