Como descobrir qual código é executado por um botão ou elemento no Chrome usando as Ferramentas do desenvolvedor

305

Estou usando o Chrome e meu próprio site.

O que eu sei por dentro:

1 ) Tenho um formulário no qual as pessoas se inscrevem clicando neste botão laranja da imagem:

insira a descrição da imagem aqui

2 ) Eu inspeciono, e isso é tudo: <img class="formSend" src="images/botoninscribirse2.png">

3 ) Na parte superior do código fonte, existem inúmeras fontes de script. Eu sei qual o botão chama porque eu o codifiquei:<script src="js/jquery2.js" type="text/javascript"></script>

4 ) Nesse arquivo, você pode encontrar: o $(".formSend").click(function() { ... });que é acionado pelo botão (para fazer uma validação e envio de formulários bastante complexos) e o que eu quero é poder descobrir isso usando as ferramentas de desenvolvimento do Chrome em qualquer site.

Como posso descobrir para onde o elemento chama?

A guia Ouvintes não funcionou para mim. Então tentei procurar os ouvintes do evento click, o que me pareceu uma aposta segura, mas ... não existe jquery2.jslá (e eu realmente não saberia qual arquivo é o código, então eu perderia tempo verificando tudo isso .. .):

insira a descrição da imagem aqui

Minha $(".formSend").click(function() { ... });função no jquery2.jsarquivo não está lá.

Jesse explica o porquê :

"Finalmente, a razão pela qual sua função não está diretamente vinculada ao manipulador de eventos click é porque o jQuery retorna uma função que é vinculada. A função do jQuery, por sua vez, passa por algumas camadas de abstração e verificações e, em algum lugar, executa sua função . "


Conforme sugerido por alguns de vocês, coletei os métodos que funcionaram em uma resposta abaixo .

Carles Alcolea
fonte
4
Eu costumo usar o Visual Eventbookmarklet. Ele detecta eventos de clique vinculados por bibliotecas populares e cria uma sobreposição do site, mostrando onde os eventos são vinculados e fornecendo exemplos de código e locais de origem para cada evento.
Kevin B
3
@DontVoteMeDown Mas isso derrota toda a questão. Suponha que eu tenha dezenas de arquivos * .js no site, como você sabe que o código acionado pelo botão está dentro do jquery2.js?
Carles Alcolea
1
Entendo como o Visual Event funciona (graças a você, BTW), mas quando você clica nesse botão, seu navegador sabe perfeitamente o que executar , porque ele é executado. Eu só quero ter certeza de que não é possível com as ferramentas de desenvolvimento e vou seguir em frente.
Carles Alcolea
1
Boa pergunta, eu definitivamente acho que este é um recurso Chrome (ou Firefox) deve ter
tomysshadow
1
Se você encontrou a resposta para esta pergunta, adicione-a como resposta. Responder a sua própria pergunta é altamente recomendável, mas responder editando sua pergunta não é.
O cara com o chapéu

Respostas:

209

A resposta de Alexander Pavlov chega mais perto do que você deseja.

Devido à extensividade da abstração e funcionalidade do jQuery, muitos aros precisam ser pulados para chegar ao ponto principal do evento. Eu configurei este jsFiddle para demonstrar o trabalho.


1. Configurando o ponto de interrupção do ouvinte de eventos

Você estava perto deste.

  1. Abra o Chrome Dev Tools (F12) e vá para a guia Fontes.
  2. Faça uma busca detalhada em Mouse -> Clique (clique para ampliar)
    Ferramentas de desenvolvimento do Chrome -> guia Fontes -> Mouse -> Clique em

2. Clique no botão!

O Chrome Dev Tools interrompe a execução do script e apresenta esse belo emaranhado de códigos minificados:

Ferramentas de desenvolvimento do Chrome pausaram a execução do script (clique para ampliar)


3. Encontre o código glorioso!

Agora, o truque aqui é não se deixar levar pela pressão da tecla e ficar de olho na tela.

  1. Pressione a F11tecla (Step In) até que o código fonte desejado apareça
  2. Código-fonte finalmente alcançado
    • Na amostra jsFiddle fornecida acima, tive que pressionar F11 108 vezes antes de alcançar a função / manipulador de eventos desejada
    • Sua milhagem pode variar, dependendo da versão do jQuery (ou biblioteca de estruturas) usada para vincular os eventos
    • Com dedicação e tempo suficientes, você pode encontrar qualquer manipulador / função de evento

Manipulador / função de evento desejado


4. Explicação

Não tenho a resposta exata ou a explicação de por que o jQuery passa por muitas camadas de abstrações - tudo o que posso sugerir é que é por causa do trabalho que faz para abstrair seu uso do navegador que executa o código .

Aqui está um jsFiddle com uma versão de depuração do jQuery (ou seja, não minificado). Quando você olha para o código no primeiro ponto de interrupção (não minificado), pode ver que o código está manipulando muitas coisas:

    // ...snip...

    if ( !(eventHandle = elemData.handle) ) {
        eventHandle = elemData.handle = function( e ) {
            // Discard the second event of a jQuery.event.trigger() and
            // when an event is called after a page has unloaded
            return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ?
                jQuery.event.dispatch.apply( elem, arguments ) : undefined;
        };
    }

    // ...snip...

A razão pela qual acho que você perdeu a tentativa quando a " execução é interrompida e eu pulo linha por linha " é porque você pode ter usado a função "Step Over", em vez de Step In. Aqui está uma resposta StackOverflow explicando as diferenças.

Finalmente, a razão pela qual sua função não está diretamente vinculada ao manipulador de eventos click é porque o jQuery retorna uma função que é vinculada. A função do jQuery, por sua vez, passa por algumas camadas e verificações de abstração e, em algum lugar , executa sua função.

Jesse
fonte
Uau, você é e @ Alexander-Pavlov totalmente certo, eu perdi. Agora, tentei novamente e preciso de 132 F11 hits! Agora faz sentido, mas é apenas impraticável. Eu vou corrigir minha pergunta embora.
Carles Alcolea
@CarlesAlcolea Yup - é absolutamente impraticável, mas não impossível. Qualquer pessoa com bastante dedicação e tempo disponível pode encontrar qualquer coisa feita em HTML e JavaScript, mesmo se escondida profundamente e minificada. Sinta-se à vontade para marcar a resposta de Alexander Pavlov, ou a minha, como aceita.
Jesse
1
sim, estou terminando agora. Para sua informação, se você ainda não o conhecia, se clicar no botão suspenso esquerdo ( i.imgur.com/ALoMQkR.png ) em um script minificado, ele será "embelezado" e funcionará durante a depuração também.
Carles Alcolea
A partir de 2014, o Chrome incorporou um recurso de caixa preta no Chrome Dev Tools, o que elimina a necessidade do item 1 acima.
Brian
1
@ Brian e aqui está um post do blog detalhando scripts de boxe preto .
Cristian Diaconescu
157

Solução 1: quadro negro de estrutura

Funciona muito bem, configuração mínima e sem terceiros.

De acordo com a documentação do Chrome :

O que acontece quando você bloqueia um script?

Exceções lançadas a partir do código da biblioteca não serão pausadas (se Pausar em exceções estiver ativado), Entrar / sair / ultrapassar ignora o código da biblioteca, os pontos de interrupção do ouvinte de eventos não quebram no código da biblioteca, o depurador não pausa em nenhum ponto de interrupção definido na biblioteca código. O resultado final é que você está depurando o código do aplicativo em vez de recursos de terceiros.

Aqui está o fluxo de trabalho atualizado:
  1. Abra as Ferramentas do desenvolvedor do Chrome ( F12ou + + i), vá para as configurações (canto superior direito ou F1). Localize uma guia à esquerda chamada " Blackboxing "

insira a descrição da imagem aqui

  1. É aqui que você coloca o padrão RegEx dos arquivos que você deseja que o Chrome ignore durante a depuração. Por exemplo: jquery\..*\.js(padrão glob / humano tradução: jquery.*.js)
  2. Se você quiser pular arquivos com vários padrões, pode adicioná-los usando o caractere de barra vertical, da seguinte |forma: jquery\..*\.js|include\.postload\.js(que age como um "ou esse padrão", por assim dizer) ou continue adicionando-os com o botão "Adicionar".
  3. Agora continue com a Solução 3 descrita abaixo.

Dica de bônus! Uso o Regex101 regularmente (mas existem muitos outros :) para testar rapidamente meus padrões de regex enferrujados e descobrir onde estou errado com o depurador de expressões regulares passo a passo. Se você ainda não é "fluente" em Expressões regulares, recomendo que comece a usar sites que o ajudem a escrevê-los e visualizá-los, como http://buildregex.com/ e https://www.debuggex.com/

Você também pode usar o menu de contexto ao trabalhar no painel Origens. Ao visualizar um arquivo, você pode clicar com o botão direito do mouse no editor e escolher Blackbox Script. Isso adicionará o arquivo à lista no painel Configurações:

insira a descrição da imagem aqui


Solução 2: Evento Visual

insira a descrição da imagem aqui

É uma excelente ferramenta para ter :

O Visual Event é um bookmarklet Javascript de código aberto que fornece informações de depuração sobre eventos que foram anexados aos elementos DOM. Visual Event mostra:

  • Quais elementos têm eventos anexados a eles
  • O tipo de eventos anexado a um elemento
  • O código que será executado com o evento é acionado
  • O arquivo de origem e o número da linha para onde a função anexada foi definida (apenas navegadores Webkit e Opera)


Solução 3: Depuração

Você pode pausar o código quando clicar em algum lugar da página ou quando o DOM for modificado ... e outros tipos de pontos de interrupção JS que serão úteis para conhecer. Você deve aplicar o blackbox aqui para evitar um pesadelo.

Nesse caso, quero saber o que acontece exatamente quando clico no botão.

  1. Abra a ferramenta Dev Tools -> Sources e, à direita, encontre Event Listener Breakpoints:

    insira a descrição da imagem aqui

  2. Expanda Mousee selecioneclick

  3. Agora clique no elemento (a execução deve pausar) e agora você está depurando o código. Você pode passar por todo o código pressionando F11(que é Step in ). Ou volte alguns saltos na pilha. Pode haver uma tonelada de saltos


Solução 4: pescar palavras-chave

Com o Dev Tools ativado, você pode pesquisar toda a base de código (todo o código em todos os arquivos) com + + Fou:

insira a descrição da imagem aqui

e pesquisar #envioou qualquer que seja a tag / classe / ID que você acha que começa a festa e você pode chegar a um lugar mais rápido do que o previsto.

Esteja ciente de que, às vezes, não há apenas imgmuitos elementos empilhados e talvez você não saiba qual deles aciona o código.


Se isso estiver um pouco fora do seu conhecimento, dê uma olhada no tutorial do Chrome sobre depuração .

Carles Alcolea
fonte
Não foi possível encontrar a caixa preta em nenhum lugar? Tente: chrome: // flags / # enable-devtools-experimentais
ruuter
1
@CarlesAlcolea AWESOME !! Você acabou de me salvar toneladas de tempo com esse truque!
Prix
alguém sabe por que, ao executar um evento visual, a página se atualiza, perdendo todas as informações?
Edu Castrillon
Para a solução 1, você precisaria clicar nas reticências no canto direito para ter acesso às CONFIGURAÇÕES DO CHROME DEVTOOLS COMPLETO ou, em vez disso, pressionar F1 quando o DevTools estiver aberto. Agora você veria o BlackBoxing como guia no lado esquerdo. Aproveitar!
pensebien
1
Parece que a nova melhor maneira de scripts de caixa preta é incrivelmente fácil. Vá para esse arquivo no painel Fontes e clique com o botão direito do mouse no arquivo (não no item da lista à esquerda, abra o arquivo e clique com o botão direito do mouse no arquivo) e selecione "Blackbox this script". Ai está!
Dan
17

Parece que a parte "... e eu pulo linha por linha ..." está errada. Você faz StepOver ou StepIn e tem certeza de que não perdeu acidentalmente a chamada relevante?

Dito isto, as estruturas de depuração podem ser tediosas exatamente por esse motivo. Para aliviar o problema, você pode habilitar o experimento "Habilitar suporte a depuração de estruturas" . Feliz depuração! :)

Alexander Pavlov
fonte
Isso funciona perfeitamente (e você está certo, eu perdi o salto), vou adicioná-lo à minha pergunta. Também me forçou a reler os padrões regex novamente: P Obrigado.
Carles Alcolea
7

Você pode usar o findHandlersJS

Você pode encontrar o manipulador fazendo no console do chrome:

findEventHandlers("click", "img.envio")

Você obterá as seguintes informações impressas no console do chrome:

  • elemento
    O elemento real em que o manipulador de eventos foi registrado

  • matriz de eventos com informações sobre os manipuladores de eventos jquery para o tipo de evento em que estamos interessados ​​(por exemplo, clique, altere etc.)
  • manipulador
    Método real do manipulador de eventos que você pode ver clicando com o botão direito do mouse e selecionando Mostrar definição de função
  • seletor
    O seletor fornecido para eventos delegados. Estará vazio para eventos diretos.
  • destinos
    Lista com os elementos que esse manipulador de eventos tem como alvo. Por exemplo, para um manipulador de eventos delegados registrado no objeto de documento e direcionado a todos os botões em uma página, essa propriedade listará todos os botões na página. Você pode passar o mouse e vê-los realçados no chrome.

Mais informações aqui e você pode experimentá-lo neste site de exemplo aqui .

Rui
fonte
3

Esta solução precisa do método de dados do jQuery .

  1. Abra o console do Chrome (embora qualquer navegador com o jQuery carregado funcione)
  2. Corre $._data($(".example").get(0), "events")
  3. Pesquise a saída para encontrar o manipulador de eventos desejado.
  4. Clique com o botão direito do mouse em "manipulador" e selecione "Mostrar definição da função"
  5. O código será mostrado na guia Fontes

$._data()está apenas acessando o método de dados do jQuery. Uma alternativa mais legível poderia ser jQuery._data().

Ponto interessante por esta resposta SO :

A partir do jQuery 1.8, os dados do evento não estão mais disponíveis na "API pública" para dados. Leia esta postagem do blog jQuery . Agora você deve usar isso:

jQuery._data( elem, "events" ); elem deve ser um elemento HTML, não um objeto jQuery ou seletor.

Observe que essa é uma estrutura interna, 'privada', e não deve ser modificada. Use isso apenas para fins de depuração.

Nas versões mais antigas do jQuery, talvez você precise usar o método antigo, que é:

jQuery( elem ).data( "events" );

Uma versão independente do jQuery seria: (jQuery._data || jQuery.data)(elem, 'events');

apptaro
fonte
2
Obrigado por lançar mais idéias. Essa é outra maneira de fazer isso. A desvantagem é que ele precisa do jQuery e o título desta pergunta pede apenas para confiar nas ferramentas do Chrome. Vou editar sua resposta para deixar claro que é um método jQuery e também usar algo mais razoável do que "MELHOR SOLUÇÃO DE SEMPRE" :) Por favor, dê uma olhada em stackoverflow.com/help/how-to-answer
Carles Alcolea