jQuery encontrar manipuladores de events registrados com um object

Eu preciso encontrar quais manipuladores de events são registrados em um object.

Por exemplo:

$("#el").click(function() {...}); $("#el").mouseover(function() {...}); 

$("#el") tem click e mouseover registrados.

Existe uma function para descobrir isso e, possivelmente, iterar sobre os manipuladores de events?

Se não for possível em um object jQuery através de methods apropriados, é possível em um object DOM simples?

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

 jQuery._data( elem, "events" ); 

elem deve ser um elemento HTML, não um object jQuery ou um seletor.

Por favor, note que esta é uma estrutura interna ‘privada’ e não deve ser modificada. Use isso apenas para fins de debugging.

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

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

Você pode fazer assim:

 $("#el").click(function(){ alert("click");}); $("#el").mouseover(function(){ alert("mouseover"); }); $.each($("#el").data("events"), function(i, e) { alert(i); }); //alerts 'click' then 'mouseover' 

Se você estiver no jQuery 1.4+, isso alertará o evento e as funções associadas a ele:

 $.each($("#el").data("events"), function(i, event) { alert(i); $.each(event, function(j, h) { alert(h.handler); }); }); //alerts: //'click' //'function (){ alert("click"); }' //'mouseover' //'function(){ alert("mouseover"); }' 

Você pode jogar com ele no jsFiddle aqui

Para jQuery 1.8+, isso não funcionará mais porque os dados internos são colocados em um object diferente.

A última versão não oficial (mas também funciona em versões anteriores, pelo menos na 1.7.2) é agora – $._data(element, "events")

O sublinhado (“_”) é o que faz a diferença aqui. Internamente, ele está chamando $.data(element, name, null, true) , o último (quarto) parâmetro é interno (“pvt”).

Plugue sem vergonha, mas você pode usar findHandlerJS

Para usá-lo, basta include findHandlersJS (ou apenas copiar e colar o código javascript bruto na janela do console do chrome) e especificar o tipo de evento e um seletor de jquery para os elementos de seu interesse.

Para o seu exemplo, você pode encontrar rapidamente os manipuladores de events que você mencionou fazendo

 findEventHandlers("click", "#el") findEventHandlers("mouseover", "#el") 

Isso é o que é retornado:

  • elemento
    O elemento real no qual o manipulador de events foi registrado
  • events
    Array com informações sobre os manipuladores de events jquery para o tipo de evento em que estamos interessados ​​(por exemplo, clicar, alterar, etc)
    • manipulador
      Método de manipulador de events real que você pode ver clicando com o botão direito e selecionando Mostrar definição de function
    • seletor
      O seletor forneceu events delegates. Estará vazio para events diretos.
    • alvos
      Listar com os elementos que esse manipulador de events aloca. Por exemplo, para um manipulador de events delegates que está registrado no object do documento e segmenta todos os botões em uma página, essa propriedade listará todos os botões da página. Você pode passar o mouse e vê-los destacados no chrome.

Você pode experimentá-lo aqui

Eu uso o plugin eventbug para o firebug para essa finalidade.

Eu combinei as duas soluções de @jps para uma function:

 jQuery.fn.getEvents = function() { if (typeof(jQuery._data) == 'function') { return jQuery._data(this.get(0), 'events') || {}; } else if (typeof(this.data) == 'function') { // jQuery version < 1.7.? return this.data('events') || {}; } return {}; }; 

Mas cuidado, esta function só pode retornar os events que foram configurados com o próprio jQuery.

A partir do 1.9 não há nenhuma maneira documentada de recuperar os events, além de usar o plug-in Migrar para restaurar o comportamento antigo. Você poderia usar o método _.data () como o jps menciona, mas esse é um método interno. Então, basta fazer a coisa certa e usar o plugin Migrate se você precisar dessa funcionalidade.

Da documentação do jQuery em .data("events")

Antes de 1.9, .data (“events”) poderia ser usado para recuperar a estrutura de dados de events internos não documentados do jQuery para um elemento se nenhum outro código tivesse definido um elemento de dados com o nome “events”. Este caso especial foi removido em 1.9. Não há interface pública para recuperar essa estrutura de dados interna e ela permanece não documentada. No entanto, o plugin jQuery Migrate restaura esse comportamento para o código que depende dele.

Em um navegador moderno com ECMAScript 5.1 / Array.prototype.map , você também pode usar

 jQuery._data(DOCUMENTELEMENT,'events')["EVENT_NAME"].map(function(elem){return elem.handler;}); 

no console do seu navegador, que imprimirá a origem dos manipuladores, delimitados por vírgulas. Útil para ver o que tudo está sendo executado em um evento específico.

Eu tenho que dizer que muitas das respostas são interessantes, mas recentemente eu tive um problema parecido e a solução foi extremamente simples indo pelo caminho DOM. É diferente porque você não itera, mas aponta diretamente para o evento que precisa, mas abaixo darei uma resposta mais geral.

Eu tive uma imagem em uma fileira:

 ...

E essa imagem tinha um manipulador de events de clique anexado a ela:

 imageNode.click(function () { ... }); 

Minha intenção era expandir a área clicável para toda a linha, então primeiro obtive todas as imagens e linhas relativas:

 tableNode.find("img.folder").each(function () { var tr; tr = $(this).closest("tr"); // < -- actual answer }); 

Agora, na linha anwer atual, fiz o seguinte, dando uma resposta à pergunta original:

 tr.click(this.onclick); 

Por isso, obtive o manipulador de events diretamente do elemento DOM e o coloquei no manipulador de events de clique do jQuery. Funciona como um encanto.

Agora, para o caso geral. Nos velhos tempos pré-jQuery você poderia ter todos os events ligados a um object com duas funções simples, mas poderosas, oferecidas a nós mortais por Douglas Crockford :

 function walkTheDOM(node, func) { func(node); node = node.firstChild; while (node) { walkTheDOM(node, func); node = node.nextSibling; } } function purgeEventHandlers(node) { walkTheDOM(node, function (n) { var f; for (f in n) { if (typeof n[f] === "function") { n[f] = null; } } }); } 

Eventos podem ser recuperados usando:

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

ou jQuery 1.8+:

 jQuery._data(elem, 'events'); 

Nota: Os events limitados usando $('selector').live('event', handler) podem ser recuperados usando:

 jQuery(document).data('events') 

Eu criei um seletor personalizado do jQuery que verifica o cache de manipuladores de events designados do jQuery, bem como os elementos que usam o método nativo para adicioná-los:

 (function($){ $.find.selectors[":"].event = function(el, pos, match) { var search = (function(str){ if (str.substring(0,2) === "on") {str = str.substring(2);} return str; })(String(match[3]).trim().toLowerCase()); if (search) { var events = $._data(el, "events"); return ((events && events.hasOwnProperty(search)) || el["on"+search]); } return false; }; })(jQuery); 

Exemplo:

 $(":event(click)") 

Isso retornará elementos que tenham um manipulador de cliques anexado a eles.

Outra maneira de fazer isso é simplesmente usar o jQuery para pegar o elemento, depois percorrer o Javascript para obter e definir e jogar com os manipuladores de events. Por exemplo:

 var oldEventHandler = $('#element')[0].onclick; // Remove event handler $('#element')[0].onclick = null; // Switch it back $('#element')[0].onclick = oldEventHandler; 

Para verificar events em um elemento:

 var events = $._data(element, "events") 

Observe que isso só funcionará com manipuladores de events diretos, se você estiver usando $ (document) .on (“event-name”, “jq-selector”, function () {// logic}), você desejará ver o function getEvents na parte inferior desta resposta

Por exemplo:

  var events = $._data(document.getElementById("myElemId"), "events") 

ou

  var events = $._data($("#myElemId")[0], "events") 

Exemplo Completo:

       
Text

Uma maneira mais completa de verificar, que inclui listeners dynamics, instalados com $ (document) .on

 function getEvents(element) { var elemEvents = $._data(element, "events"); var allDocEvnts = $._data(document, "events"); for(var evntType in allDocEvnts) { if(allDocEvnts.hasOwnProperty(evntType)) { var evts = allDocEvnts[evntType]; for(var i = 0; i < evts.length; i++) { if($(element).is(evts[i].selector)) { if(elemEvents == null) { elemEvents = {}; } if(!elemEvents.hasOwnProperty(evntType)) { elemEvents[evntType] = []; } elemEvents[evntType].push(evts[i]); } } } } return elemEvents; } 

Exemplo de uso:

 getEvents($('#myElemId')[0])