obtener elemento ejemplo javascript events dom

javascript - elemento - innerhtml



¿Cómo encontrar escuchas de eventos en un nodo DOM al depurar o desde el código JavaScript? (17)

Tengo una página en la que algunos oyentes de eventos se adjuntan a cuadros de entrada y cuadros de selección. ¿Hay alguna forma 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. AddEventListener de DOM;
  3. Como elemento del elemento element.onclick .

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

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

  1. Evento visual
  2. La sección Elementos de las Herramientas de desarrollo de Chrome: seleccione un elemento y busque "Escuchas de eventos" en la parte inferior derecha (similar en Firefox)

Si desea usar los eventos en su código, y está usando jQuery antes de la versión 1.8 , puede usar:

$(selector).data("events")

para conseguir los eventos. A partir de la versión 1.8, se descontinúa el uso de .data ("eventos") (consulte este ticket de error ). Puedes usar:

$._data(element, "events")

Otro ejemplo: escriba todos los eventos de clic en un enlace determinado 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 podría cambiar en futuras versiones. Desafortunadamente, no conozco ningún otro medio fácil de acceder a los eventos.


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

2: Puede anular Element.addEventListener para recordar los escuchas agregados (la propiedad práctica EventListenerList se eliminó 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 por:

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 necesita un cuidado especial aquí:

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

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

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

Así que necesitas manejarlo, también:

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

El bookmarklet Evento Visual (mencionado en la respuesta más popular) solo roba el caché de manejador de biblioteca personalizado:

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 en particular. Si bien esto puede parecer un descuido, hubo una propuesta para incluir una propiedad llamada eventListenerList en la especificación DOM de nivel 3, pero desafortunadamente se eliminó en borradores posteriores. Como tal, nos vemos obligados a mirar las bibliotecas de Javascript individuales, que normalmente mantienen un caché de eventos adjuntos (para que luego puedan eliminarse y realizar otras abstracciones útiles).

Como tal, para que Visual Event muestre eventos, debe poder analizar la información del evento fuera de una biblioteca de Javascript.

La anulación de elementos puede ser cuestionable (es decir, porque hay algunas características específicas de DOM como colecciones en vivo, que no pueden codificarse en JS), pero le da soporte al eventListenerList de forma nativa y funciona en Chrome, Firefox y Opera (no funciona en IE7) ).



Depende de cómo se adjuntan los eventos. Para la ilustración presume 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) controlador de evento único

element.onclick = handler; // inspect alert(element.onclick); // alerts "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) { alert(value) // alerts "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) { alert(handlerObj.handler) // alerts "function() { alert(''clicked!'') }" // also available: handlerObj.type, handlerObj.namespace })

(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) { alert(item[2]) // alerts "function() { alert(''clicked!'') }" } })

  • 1.6 a 1.6.0.3, inclusive (se puso 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 (un poco mejor)

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


Estoy tratando de hacer eso en jQuery 2.1, y con el método " $().click() -> $(element).data("events").click; " no funciona.

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

$(document).ready(function(){ var node = $(''body''); // Bind 3 events to body click node.click(function(e) { alert(''hello''); }) .click(function(e) { alert(''bye''); }) .click(fun_1); // Inspect the events of body var events = $._data(node[0], "events").click; var ev1 = events[0].handler // -> function(e) { alert(''hello'') var ev2 = events[1].handler // -> function(e) { alert(''bye'') var ev3 = events[2].handler // -> function fun_1() $(''body'') .append(''<p> Event1 = '' + eval(ev1).toString() + ''</p>'') .append(''<p> Event2 = '' + eval(ev2).toString() + ''</p>'') .append(''<p> Event3 = '' + eval(ev3).toString() + ''</p>''); }); function fun_1() { var txt = ''text del missatge''; alert(txt); }

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <body> </body>



Las herramientas de desarrollo de Firefox ahora hacen esto. Los eventos se muestran haciendo clic en el botón "ev" a la derecha de la pantalla de cada elemento, incluidos los eventos de jQuery y DOM .


Opera 12 (no es el último motor de Chrome Webkit basado) Dragonfly ha tenido esto por un tiempo y obviamente se muestra en la estructura DOM. En mi opinión, es un depurador superior y es la única razón restante por la que todavía utilizo la versión basada en Opera 12 (no hay v13, versión v14 y el v15 Webkit aún no tiene Dragonfly)


Prototipo 1.7.1 camino

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]; }


Puede ajustar los métodos DOM nativos para administrar los escuchas de eventos colocando esto 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


Recientemente estuve trabajando con eventos y quería ver / controlar todos los eventos en una página. Habiendo examinado las posibles soluciones, he decidido seguir mi propio camino y crear un sistema personalizado para monitorear eventos. Entonces, hice tres cosas.

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

A continuación, creé un objeto EventListener para contener la información necesaria para el evento, es decir: target , type , callback , options , useCapture , wantsUntrusted y agregue un método remove() para eliminar el oyente.

Por último, extendí los métodos nativos addEventListener() y removeEventListener() para hacer que funcionen con los objetos que he creado ( EventListener y EventListeners ).

Uso:

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

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

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

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

Manifestación

Digamos que queremos conocer a cada oyente de eventos en esta página actual. Podemos hacerlo (suponiendo que esté utilizando una extensión de administrador de scripts, Tampermonkey en este caso). El siguiente script hace esto:

// ==UserScript== // @name New Userscript // @namespace http://tampermonkey.net/ // @version 0.1 // @description try to take over the world! // @author You // @include https://.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 listamos a todos los oyentes, dice que hay 299 oyentes de eventos. "Parece" que hay algunos duplicados, pero no sé si realmente son duplicados. No todos los tipos de eventos están duplicados, por lo que todos esos "duplicados" pueden ser un oyente individual.

El código se puede encontrar en mi repository. No quise publicarlo aquí porque es bastante largo.

Actualización: Esto no parece funcionar con jQuery. Cuando examino el EventListener, veo que la devolución de llamada es

function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}

Creo que esto pertenece a jQuery, y no es la devolución de llamada real. jQuery almacena la devolución de llamada real en las propiedades del EventTarget:

$(document.body).click(function () { console.log("jquery click"); });

Para eliminar un detector de eventos, la devolución de llamada real debe pasarse al método removeEventListener() . Entonces, para hacer que esto funcione con jQuery, se necesita una modificación adicional. Podría arreglar eso en el futuro.


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

Actualización : Visual Event 2 disponible;


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

Tratar:

console.dir(clickEvents);

o

console.dir(window);


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. No se rompe mucho de todos modos.)

(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 la lista de escuchas de eventos, si el nombre está configurado, devuelve la matriz de escuchas para ese evento

someElement.clearEventListeners([name]) : elimina todos los escuchas de eventos, si el nombre está configurado solo elimina los escuchas de ese evento


Utilice getEventListeners en Google Chrome :

getEventListeners(document.getElementByID(''btnlogin'')); getEventListeners($(''#btnlogin''));


WebKit Inspector en los navegadores Chrome o Safari ahora hace esto. Mostrará los escuchas de eventos para un elemento DOM cuando lo seleccione en el panel Elementos.


Es posible enumerar todos los oyentes de eventos en JavaScript: no es tan difícil; solo tienes que hackear el método del prototype 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 de anclaje ( a ) tendrá una propiedad lastListenerInfo que contiene todos sus escuchas. E incluso funciona para eliminar oyentes con funciones anónimas.