¿Cómo encontrar detectores de eventos en un nodo DOM en JavaScript o en depuración?
Tengo una página donde algunos detectores de eventos están adjuntos a cuadros de entrada y cuadros de selección. ¿Hay alguna manera de saber qué detectores de eventos están observando un nodo DOM en particular y para qué evento?
Los eventos se adjuntan usando:
- Prototipos
Event.observe
; - DOM
addEventListener
; - Como atributo de elemento
element.onclick
.
Soporte para Chrome, Vivaldi y Safari getEventListeners(domElement)
en su consola de herramientas para desarrolladores.
Para la mayoría de los propósitos de depuración, esto podría usarse.
A continuación se muestra una muy buena referencia para usarlo:
función getEventListeners
Consejo altamente votado de Clifford Fajardo a partir de los comentarios:
getEventListeners($0)
Obtendrá los detectores de eventos para el elemento en el que se ha centrado en las herramientas de desarrollo de Chrome.
Si solo necesita inspeccionar lo que sucede en una página, puede probar el marcador de eventos visuales .
Actualización : Evento visual 2 disponible.
Depende de cómo se adjuntan los eventos. A modo de ilustración, supongamos que tenemos el siguiente controlador de clic:
var handler = function() { alert('clicked!') };
Lo adjuntaremos a nuestro elemento usando diferentes métodos, algunos que permiten la inspección y otros que no.
Método A) controlador de evento único
element.onclick = handler;
// inspect
console.log(element.onclick); // "function() { alert('clicked!') }"
Método B) múltiples controladores 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
// inspect var clickEvents = $(element).data("events").click; jQuery.each(clickEvents, function(key, value) { console.log(value) // "function() { alert('clicked!') }" })
1.4.x (almacena el controlador dentro de un objeto)
// inspect var clickEvents = $(element).data("events").click; jQuery.each(clickEvents, function(key, handlerObj) { console.log(handlerObj.handler) // "function() { alert('clicked!') }" // also available: handlerObj.type, handlerObj.namespace })
1.7+ (muy bueno)
Elaborado utilizando el conocimiento de este comentario .
events = $._data(this, 'events'); for (type in events) { events[type].forEach(function (event) { console.log(event['handler']); }); }
(Ver jQuery.fn.data
y jQuery.data
)
Método D): Prototipo (desordenado)
$(element).observe('click', handler);
1.5.x
// inspect Event.observers.each(function(item) { if(item[0] == element) { console.log(item[2]) // "function() { alert('clicked!') }" } })
1.6 a 1.6.0.3, inclusive (aquí se volvió muy difícil)
// 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){ console.log(wrapper.handler) // "function() { alert('clicked!') }" })
1.6.1 (un poco mejor)
// inspect var clickEvents = element.getStorage().get('prototype_event_registry').get('click'); clickEvents.each(function(wrapper){ console.log(wrapper.handler) // "function() { alert('clicked!') }" })
Al hacer clic en la salida resultante en la consola (que muestra el texto de la función), la consola navegará directamente a la línea de declaración de la función en el archivo JS correspondiente.
WebKit Inspector en los navegadores Chrome o Safari ahora hace esto. Mostrará los detectores de eventos para un elemento DOM cuando lo seleccione en el panel Elementos.
Es posible enumerar todos los detectores de eventos en JavaScript: no es tan difícil; sólo tienes que hackear el prototype
método de los elementos HTML ( antes de agregar los 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 ancla ( a
) tendrá una lastListenerInfo
propiedad que contiene a todos sus oyentes. E incluso funciona para eliminar oyentes con funciones anónimas.