Como depurar ligações de eventos JavaScript / jQuery com Firebug ou ferramentas similares?

609

Preciso depurar um aplicativo Web que use jQuery para fazer alguma manipulação DOM bastante complexa e confusa . A certa altura, alguns dos eventos vinculados a elementos específicos não são acionados e simplesmente param de funcionar.

Se eu tivesse a capacidade de editar a fonte do aplicativo, faria uma pesquisa detalhada e adicionaria várias console.log() instruções do Firebug e comentar / descomentar partes do código para tentar identificar o problema. Mas vamos supor que eu não possa editar o código do aplicativo e precise trabalhar inteiramente no Firefox usando o Firebug ou ferramentas semelhantes.

O Firebug é muito bom em me permitir navegar e manipular o DOM. Até agora, porém, não consegui descobrir como fazer a depuração de eventos com o Firebug. Especificamente, eu só quero ver uma lista de manipuladores de eventos vinculados a um elemento específico em um determinado momento (usando pontos de interrupção do Firebug JavaScript para rastrear as alterações). Mas o Firebug não tem a capacidade de ver eventos vinculados ou sou muito burro para encontrá-lo. :-)

Alguma recomendação ou idéia? Idealmente, gostaria de ver e editar eventos vinculados a elementos, da mesma forma que posso editar o DOM hoje.

Jaanus
fonte

Respostas:

355

Consulte Como localizar ouvintes de eventos em um nó DOM .

Em poucas palavras, supondo que em algum momento um manipulador de eventos esteja anexado ao seu elemento (por exemplo): $('#foo').click(function() { console.log('clicked!') });

Você a inspeciona assim:

  • 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!') }"
    })

Veja jQuery.fn.data(onde o jQuery armazena seu manipulador 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!') }"
    })
Crescent Fresh
fonte
21
FYI: Este não irá exibir eventos que não foram anexadas com jQuery
Juan Mendes
10
Concordo totalmente com o console.log (), no entanto, ele deve ser protegido por algo como if (window.console)no caso de ser deixado no código (muito mais fácil de fazer do que com alert ()) e interromper o IE.
thepeer
14
@thepeer Pessoalmente, prefiro fazer uma verificação no console no início do arquivo e, se ele não existir, criar um objeto fictício.
Andrew
Abaixo está um trecho semelhante para depurar todos os eventos (desculpe a falta de formatação):$('#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: veja a resposta vinculada nesta resposta. (tl; dr: você não pode).
Crescent Fresh
162

Existe um bom bookmarklet chamado Visual Event que pode mostrar todos os eventos anexados a um elemento. Possui destaques codificados por cores para diferentes tipos de eventos (mouse, teclado etc.). Quando você passa o mouse sobre eles, ele mostra o corpo do manipulador de eventos, como foi anexado e o número do arquivo / linha (no WebKit e Opera). Você também pode acionar o evento manualmente.

Ele não consegue encontrar todos os eventos porque não há uma maneira padrão de procurar quais manipuladores de eventos estão anexados a um elemento, mas funciona com bibliotecas populares como jQuery, Prototype, MooTools, YUI etc.

Matthew Crumley
fonte
8
Observe que, como isso é executado no conteúdo JavaScript, ele obtém seus dados consultando bibliotecas JavaScript. Portanto, ele mostrará apenas eventos adicionados com uma biblioteca suportada (que inclui jQuery).
Matthew Flaschen
41

Você poderia usar o FireQuery . Ele mostra todos os eventos anexados aos elementos DOM na guia HTML do Firebug. Ele também mostra todos os dados anexados aos elementos $.data.

Shrikant Sharat
fonte
1
Esse plug-in tem uma grande desvantagem: quando você está depurando e deseja inspecionar o valor de uma variável que contém uma coleção de jquery, não é possível inspecionar o valor quando o código está em pausa. Esta não é a causa do firebug. A razão para eu desinstalá-lo. sozinho
Maarten Kieft
1
Não FireQuery não parecem mostrar eventos anexados mais :(
Matty J
26

Aqui está um plugin que pode listar todos os manipuladores de eventos para qualquer elemento / evento:

$.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 );
               });
           }
        });
    });
};

Use-o assim:

// 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: (meu blog) -> http://james.padolsey.com/javascript/debug-jquery-events-with-listhandlers/

James
fonte
11

Use $._data(htmlElement, "events")no jquery 1.7+;

ex:

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

Tamás Pap
fonte
8

Como sugeriu um colega, console.log> alert:

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

O jQuery armazena eventos do seguinte modo:

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

Fazer a console.log($("a#somefoo").data("events"))deve listar os eventos anexados a esse elemento.

Alex Heyd
fonte
5

Usando o DevTools no Chrome mais recente (v29), considero estas duas dicas muito úteis para a depuração de eventos:

  1. Listando eventos jQuery do último elemento DOM selecionado

    • Inspecionar um elemento na página
    • digite o seguinte no console:

      $ ._ data ( $ 0 , "events") // assumindo o jQuery 1.7+

    • Ele listará todos os objetos de evento jQuery associados a ele, expanda o evento interessado, clique com o botão direito do mouse na função da propriedade "manipulador" e escolha "Mostrar definição da função". Ele abrirá o arquivo que contém a função especificada.

  2. Utilizando o Comando monitorEvents ()

mateuscb
fonte
4

Parece que a equipe do FireBug está trabalhando em uma extensão do EventBug. Ele adicionará outro painel ao FireBug - Events.

"O painel de eventos listará todos os manipuladores de eventos na página agrupados por tipo de evento. Para cada tipo de evento, você pode abrir para ver os elementos aos quais os ouvintes estão vinculados e o resumo da fonte da função." EventBug Rising

Embora eles não possam dizer agora quando será lançado.

jayarjo
fonte
2
Esse recurso foi lançado e incluído no FireBug 2.0.1. Agora, quando você inspeciona um elemento HTML em uma página, há um novo painel "Eventos" onde é possível ver os eventos anexados e seus manipuladores.
Derloopkat 9/08/14
4

Também encontrei o jQuery Debugger na loja do Chrome. Você pode clicar em um item dom e ele mostrará todos os eventos associados a ele, juntamente com a função de retorno de chamada. Eu estava depurando um aplicativo em que os eventos não estavam sendo removidos corretamente e isso me ajudou a encontrá-lo em questão de minutos. Obviamente, isso é para o Chrome, não para o Firefox.

Roubar
fonte
4

ev ícone ao lado de elementos

No painel Inspetor das Ferramentas para Desenvolvedor do Firefox , lista todos os eventos vinculados a um elemento.

Primeiro, selecione um elemento com Ctrl+ Shift+ C, por exemplo, a seta upvote do Stack Overflow.

Clique no evícone à direita do elemento e uma caixa de diálogo é aberta:

dica de ferramenta de eventos

Clique no ||símbolo do sinal de pausa para o evento desejado e isso abre o depurador na linha do manipulador.

Agora você pode colocar um ponto de interrupção lá como de costume no depurador, clicando na margem esquerda da linha.

Isso é mencionado em: https://developer.mozilla.org/en-US/docs/Tools/Page_Inspector/How_to/Examine_event_listeners

Infelizmente, não consegui encontrar uma maneira de jogar bem com a prettyfication, apenas parece abrir na linha reduzida: Como embelezar Javascript e CSS no Firefox / Firebug?

Testado no Firefox 42.

Ciro Santilli adicionou uma nova foto
fonte
Infelizmente, isso não funciona bem para localizar ouvintes herdados.
Chukko
3

De acordo com este segmento , no Firebug não há como ver quais eventos estão anexados aos ouvintes em um elemento DOM.

Parece que o melhor que você pode fazer é o que tj111 sugere ou pode clicar com o botão direito do mouse no elemento no visualizador de HTML e clicar em "Log Events" para poder ver quais eventos estão disparando para um elemento DOM específico. Suponho que alguém poderia fazer isso para ver quais eventos poderiam estar disparando funções específicas.

Dan Lew
fonte
2

Com a versão 2.0, o Firebug introduziu um painel Eventos , que lista todos os eventos para o elemento atualmente selecionado no painel HTML .

* Eventos * painel lateral no Firebug

Ele também pode exibir ouvintes de eventos agrupados em ligações de eventos jQuery, caso a opção Mostrar ouvintes agrupados esteja marcada, que você pode acessar através do menu de opções do painel Eventos .

Com esse painel, o fluxo de trabalho para depurar um manipulador de eventos é o seguinte:

  1. Selecione o elemento com o ouvinte de evento que você deseja depurar
  2. Dentro do painel lateral Eventos , clique com o botão direito do mouse na função no evento relacionado e escolha Definir Ponto de Interrupção
  3. Acionar o evento

=> A execução do script será interrompida na primeira linha da função do manipulador de eventos e você poderá depurar a etapa.

Sebastian Zartner
fonte
0

O Firebug 2 agora incorpora depuração / inspeção de eventos DOM.

MRalwasser
fonte