¿Cómo depurar enlaces de eventos JavaScript / jQuery con Firebug o herramientas similares?

609

Necesito depurar una aplicación web que usa jQuery para hacer una manipulación DOM bastante compleja y desordenada . En un momento, algunos de los eventos que estaban vinculados a elementos particulares, no se disparan y simplemente dejan de funcionar.

Si tuviera la capacidad de editar el origen de la aplicación, profundizaría y agregaría un montón de declaraciones de Firebug console.log() y comentarios / fragmentos de código sin comentar para tratar de identificar el problema. Pero supongamos que no puedo editar el código de la aplicación y necesito trabajar completamente en Firefox usando Firebug o herramientas similares.

Firebug es muy bueno al permitirme navegar y manipular el DOM. Hasta ahora, sin embargo, no he podido descubrir cómo hacer la depuración de eventos con Firebug. Específicamente, solo quiero ver una lista de controladores de eventos vinculados a un elemento en particular en un momento dado (usando puntos de interrupción de Firebug JavaScript para rastrear los cambios). Pero Firebug no tiene la capacidad de ver eventos vinculados, o soy demasiado tonto para encontrarlo. :-)

¿Alguna recomendación o idea? Idealmente, me gustaría ver y editar eventos vinculados a elementos, de manera similar a cómo puedo editar DOM hoy.

Jaanus
fuente

Respuestas:

355

Consulte Cómo encontrar oyentes de eventos en un nodo DOM .

En pocas palabras, suponiendo que en algún momento se adjunte un controlador de eventos a su elemento (por ejemplo): $('#foo').click(function() { console.log('clicked!') });

Lo inspeccionas así:

  • jQuery 1.3.x

    var clickEvents = $('#foo').data("events").click;
    jQuery.each(clickEvents, function(key, value) {
      console.log(value) // prints "function() { console.log('clicked!') }"
    })
  • jQuery 1.4.x

    var clickEvents = $('#foo').data("events").click;
    jQuery.each(clickEvents, function(key, handlerObj) {
      console.log(handlerObj.handler) // prints "function() { console.log('clicked!') }"
    })

Ver jQuery.fn.data(donde jQuery almacena su controlador internamente).

  • jQuery 1.8.x

    var clickEvents = $._data($('#foo')[0], "events").click;
    jQuery.each(clickEvents, function(key, handlerObj) {
      console.log(handlerObj.handler) // prints "function() { console.log('clicked!') }"
    })
Creciente Fresco
fuente
21
FYI: Esto no mostrará eventos que no se adjuntaron con jQuery
Juan Mendes
10
Totalmente de acuerdo con console.log (), sin embargo, debe cubrirse con algo así if (window.console)en caso de que quede en el código (mucho más fácil de hacer que con alert ()) y rompa IE.
thepeer
14
@thepeer Personalmente, prefiero hacer una comprobación de la consola al comienzo del archivo y, si no existe, crear un objeto ficticio.
Andrew
A continuación hay un fragmento similar para depurar todos los eventos (disculpe la falta de formato):$('#foo').click(function(event) { var events = $(this).data('events'); $.each(events, function(event, handlers) { $.each(handlers, function(key, handlerObj) { console.log("--------------------------------------"); console.log(event+"["+key+"] | "+handlerObj.handler) ; }); });
Corey O.
3
@ BrainSlugs83: vea la respuesta vinculada en esta respuesta. (tl; dr: no puedes).
Crescent Fresh
162

Hay un bonito marcador llamado Visual Event que puede mostrar todos los eventos adjuntos a un elemento. Tiene resaltados codificados por colores para diferentes tipos de eventos (mouse, teclado, etc.). Cuando pasa el cursor sobre ellos, muestra el cuerpo del controlador de eventos, cómo se adjuntó y el número de archivo / línea (en WebKit y Opera). También puede activar el evento manualmente.

No puede encontrar todos los eventos porque no hay una forma estándar de buscar qué controladores de eventos están asociados a un elemento, pero funciona con bibliotecas populares como jQuery, Prototype, MooTools, YUI, etc.

Matthew Crumley
fuente
8
Tenga en cuenta que dado que esto se ejecuta en JavaScript de contenido, obtiene sus datos al consultar las bibliotecas de JavaScript. Por lo tanto, solo mostrará eventos agregados con una biblioteca compatible (que incluye jQuery).
Matthew Flaschen
41

Podrías usar FireQuery . Muestra cualquier evento adjunto a elementos DOM en la pestaña HTML de Firebug. También muestra los datos adjuntos a los elementos a través de $.data.

Shrikant Sharat
fuente
1
Ese complemento tiene 1 gran inconveniente: cuando está depurando y desea inspeccionar el valor de una variable que contiene una colección jquery, no puede inspeccionar el valor cuando su código está en pausa. Esta no es la causa con firebug. La razón para que lo desinstale. solo
Maarten Kieft
1
FireQuery ya no parece mostrar eventos adjuntos :(
Matty J
26

Aquí hay un complemento que puede enumerar todos los controladores de eventos para cualquier elemento / evento dado:

$.fn.listHandlers = function(events, outputFunction) {
    return this.each(function(i){
        var elem = this,
            dEvents = $(this).data('events');
        if (!dEvents) {return;}
        $.each(dEvents, function(name, handler){
            if((new RegExp('^(' + (events === '*' ? '.+' : events.replace(',','|').replace(/^on/i,'')) + ')$' ,'i')).test(name)) {
               $.each(handler, function(i,handler){
                   outputFunction(elem, '\n' + i + ': [' + name + '] : ' + handler );
               });
           }
        });
    });
};

Úselo así:

// List all onclick handlers of all anchor elements:
$('a').listHandlers('onclick', console.info);

// List all handlers for all events of all elements:
$('*').listHandlers('*', console.info);

// Write a custom output function:
$('#whatever').listHandlers('click',function(element,data){
    $('body').prepend('<br />' + element.nodeName + ': <br /><pre>' + data + '<\/pre>');
});

Src: (mi blog) -> http://james.padolsey.com/javascript/debug-jquery-events-with-listhandlers/

James
fuente
11

Uso $._data(htmlElement, "events")en jquery 1.7+;

ex:

$._data(document, "events") o $._data($('.class_name').get(0), "events")

Tamás Pap
fuente
8

Como sugirió un colega, console.log> alert:

var clickEvents = $('#foo').data("events").click;
jQuery.each(clickEvents, function(key, value) {
    console.log(value);
})
Flevour
fuente
6

jQuery almacena eventos en lo siguiente:

$("a#somefoo").data("events")

Hacer un console.log($("a#somefoo").data("events"))debe enumerar los eventos adjuntos a ese elemento.

Alex Heyd
fuente
5

Usando DevTools en el último Chrome (v29), encuentro estos dos consejos muy útiles para depurar eventos:

  1. Listado de eventos jQuery del último elemento DOM seleccionado

    • Inspeccionar un elemento en la página
    • escriba lo siguiente en la consola:

      $ ._ data ( $ 0 , "eventos") // suponiendo que jQuery 1.7+

    • Enumerará todos los objetos de evento jQuery asociados con él, expandirá el evento interesado, haga clic con el botón derecho en la función de la propiedad "controlador" y seleccione "Mostrar definición de función". Se abrirá el archivo que contiene la función especificada.

  2. Utilizando el comando monitorEvents ()

mateuscb
fuente
4

Parece que el equipo de FireBug está trabajando en una extensión de EventBug. Agregará otro panel a FireBug - Eventos.

"El panel de eventos enumerará todos los controladores de eventos en la página agrupados por tipo de evento. Para cada tipo de evento, puede abrir para ver los elementos a los que están vinculados los oyentes y un resumen del origen de la función". EventBug Rising

Aunque no pueden decir en este momento cuándo será lanzado.

jayarjo
fuente
2
Esta característica fue lanzada e incluida en FireBug 2.0.1. Ahora, cuando inspecciona un elemento HTML en una página, hay un nuevo panel "Eventos" donde puede ver los eventos adjuntos y sus controladores.
derloopkat
4

También encontré jQuery Debugger en la tienda de Chrome. Puede hacer clic en un elemento dom y mostrará todos los eventos vinculados junto con la función de devolución de llamada. Estaba depurando una aplicación donde los eventos no se eliminaban correctamente y esto me ayudó a rastrearlo en minutos. Obviamente, esto es para Chrome, no para Firefox.

Robar
fuente
4

ev icono al lado de elementos

Dentro del panel Inspector de Firefox Developer Tools , se enumeran todos los eventos vinculados a un elemento.

Primero seleccione un elemento con Ctrl+ Shift+ C, por ejemplo, la flecha de votación positiva de Stack Overflow.

Haga clic en el evicono a la derecha del elemento y se abrirá un diálogo:

información sobre herramientas de eventos

Haga clic en el ||símbolo de signo de pausa para el evento que desee, y esto abrirá el depurador en la línea del controlador.

Ahora puede colocar un punto de interrupción como de costumbre en el depurador, haciendo clic en el margen izquierdo de la línea.

Esto se menciona en: https://developer.mozilla.org/en-US/docs/Tools/Page_Inspector/How_to/Examine_event_listeners

Desafortunadamente, no pude encontrar una manera de que esto funcione bien con prettyfication, solo parece abrirse en la línea minimizada: ¿Cómo embellecer Javascript y CSS en Firefox / Firebug?

Probado en Firefox 42.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
fuente
Desafortunadamente, esto no funciona bien para localizar oyentes heredados.
chukko
3

De acuerdo con este hilo , no hay forma en Firebug de ver qué eventos están asociados a los oyentes en un elemento DOM.

Parece que lo mejor que puede hacer es lo que sugiere tj111, o puede hacer clic derecho en el elemento en el visor HTML y hacer clic en "Registrar eventos" para que pueda ver qué eventos se están activando para un elemento DOM particular. Supongo que uno podría hacer eso para ver qué eventos podrían estar activando funciones particulares.

Dan Lew
fuente
2

Con la versión 2.0, Firebug introdujo un panel de Eventos , que enumera todos los eventos para el elemento actualmente seleccionado dentro del panel HTML .

* Eventos * panel lateral en Firebug

También puede mostrar oyentes de eventos envueltos en enlaces de eventos jQuery en caso de que la opción Mostrar oyentes envueltos esté marcada, a la que puede acceder a través del menú de opciones del panel Eventos .

Con ese panel, el flujo de trabajo para depurar un controlador de eventos es el siguiente:

  1. Seleccione el elemento con el detector de eventos que desea depurar
  2. Dentro del panel lateral Eventos , haga clic con el botón derecho en la función debajo del evento relacionado y elija Establecer punto de interrupción
  3. Activa el evento

=> La ejecución del script se detendrá en la primera línea de la función del controlador de eventos y puede depurarla paso a paso.

Sebastian Zartner
fuente
0

Firebug 2 ahora incorpora la depuración / inspección de eventos DOM.

MRalwasser
fuente