jQuery encontra os manipuladores de eventos registados com um objecto

Preciso de descobrir quais os responsáveis por eventos registados sobre um objecto.

por exemplo:

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

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

Há alguma função para descobrir isso e, possivelmente, sobre os responsáveis pelos eventos?

Se não é possível num objecto jQuery através de métodos adequados, é possível num objecto dom simples?

Author: Ian, 2010-03-25

14 answers

A partir de jquery 1.8, os dados do evento já não estão disponíveis na "API pública" para os dados. Leia este post de jQuery no blog . Agora deve usar isto em vez disso:
jQuery._data( elem, "events" );

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

Por favor, note que esta é uma estrutura interna, 'privada', e não deve ser modificada. Use isto apenas para depuração.

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

jQuery( elem ).data( "events" );
 627
Author: jps, 2013-01-10 17:15:09

Podes fazê-lo 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 estiver em jQuery 1.4+, isto alertará o evento e as funções ligadas 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"); }'

Podes brincar com ele aqui no jsFiddle. ​

 75
Author: Nick Craver, 2010-03-25 20:34:04

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

A última forma não oficial (mas funciona também em versões anteriores, pelo menos em 1.7.2) de o fazer 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 é um interno ("pvt").

 36
Author: PhistucK, 2012-09-12 15:09:08
Plug Sem vergonha, mas pode usar findHandlerJS

Para o usar, só terá de incluir o findHandlersJS (ou apenas copiar e colar o código de javascript {[[11]}em bruto para a janela da consola do chrome) e indicar o tipo de Evento e um selector de jquery para os elementos em que está interessado.

Para o seu exemplo, você poderia rapidamente encontrar os manipuladores de eventos que mencionou ao fazer

findEventHandlers("click", "#el")
findEventHandlers("mouseover", "#el")
Isto é o que é devolvido.
  • elemento
    O elemento efectivo em que o responsável pelo evento foi registado em
  • eventos
    Array com informações sobre os gerentes de eventos jquery para o tipo de evento em que estamos interessados (por exemplo, clique, mudança, etc)
    • manipulador
      Método actual de tratamento de eventos que poderá ver se carregar com o botão direito nele e seleccionar a opção Mostrar a definição da função
    • selector
      O selector previa eventos delegados. Estará vazia para eventos diretos.
    • alvos
      Lista com os elementos que este manipulador de Eventos é o alvo. Por exemplo, para um manipulador de eventos delegado que é registrado no objeto do documento e Visa todos os botões em uma página, esta propriedade irá listar todos os botões na página. Você pode pairá-los e vê-los realçados em cromo.
Podes tentar. toma.
 29
Author: Rui, 2016-01-13 16:44:04

USO 'plugin' de eventbug para o firebug para este fim.

 13
Author: Anton, 2012-07-26 06:10:30

Combinei ambas as soluções de @jps para uma função:

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 função só pode devolver os eventos que foram criados com jQuery.
 8
Author: algorhythm, 2014-11-14 23:20:10

A partir de 1.9 não há nenhuma maneira documentada de recuperar os eventos, a não ser usar o plugin Migrate para restaurar o comportamento antigo. Podias usar o _.método de dados() como o jps menciona, mas este é um método interno. Por isso, basta fazer a coisa certa e usar o plugin migrar se você precisa desta funcionalidade.

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

Antes de 1, 9,Dados ("eventos") podem ser usados para recuperar o jQuery estrutura de dados internos de eventos não documentados para um elemento se nenhum outro code tinha definido um elemento de dados com o nome "eventos". Este especial o caso foi removido em 1.9. Não existe nenhuma interface pública para recuperar esta estrutura de dados internos, e continua sem documentação. Entanto, o 'plugin' de migração jQuery restaura este comportamento para o código que depende é para já.

 6
Author: oligofren, 2013-05-27 10:06:45

Num navegador moderno com ECMAScript 5.1 / Array.prototype.map, também pode usar

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

Na sua consola do navegador, que irá imprimir a fonte dos manipuladores, vírgula delimitada. Útil para olhar para o que tudo está rodando em um evento particular.

 3
Author: Jesan Fafon, 2014-11-10 16:04:01
Tenho de dizer que muitas das respostas são interessantes, mas recentemente tive um problema semelhante e a solução foi extremamente simples seguindo o caminho do DOM. É diferente porque você não itera, mas aponta diretamente para o evento que você precisa, mas abaixo eu vou dar uma resposta mais geral.

Eu tinha uma imagem seguida:

<table>
  <td><tr><img class="folder" /></tr><tr>...</tr></td>
</table>

E essa imagem tinha um manipulador de eventos ligado a ela:

imageNode.click(function () { ... });
A minha intenção era expandir a área clicável para toda a fila, por isso, primeiro consegui tudo. imagens e linhas relativas:
tableNode.find("img.folder").each(function () {
  var tr;

  tr = $(this).closest("tr");
  // <-- actual answer
});

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

tr.click(this.onclick);

Então, fui buscar o controlador de eventos directamente do elemento DOM e coloquei-o no controlador de eventos do botão jQuery. Funciona lindamente.

Agora, ao caso geral. Nos velhos tempos pré-jQuery, podíamos juntar todos os eventos a um objecto com duas funções simples, mas poderosas, dotadas de 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;
      }
    }
  });
}
 2
Author: pid, 2014-10-14 14:49:50

Os eventos podem ser recuperados usando:

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

Ou jQuery 1, 8+:

jQuery._data(elem, 'events');

Nota: Eventos limitados usando $('selector').live('event', handler) pode ser obtido utilizando:

jQuery(document).data('events')
 2
Author: R. Oosterholt, 2015-12-03 15:03:26

Eu criei um selector jQuery personalizado que verifica tanto o cache do jQuery dos manipuladores de eventos atribuídos, 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)")

Isto irá devolver os elementos que têm um manipulador de click ligado a eles.

 2
Author: Erutan409, 2017-11-07 19:40:09

Outra Maneira de fazê-lo é apenas usar o jQuery para agarrar o elemento, em seguida, passar por Javascript real para começar e definir e jogar com os manipuladores de eventos. Por exemplo:

var oldEventHandler = $('#element')[0].onclick;
// Remove event handler
$('#element')[0].onclick = null;
// Switch it back
$('#element')[0].onclick = oldEventHandler;
 1
Author: tempranova, 2016-04-06 09:32:48

Tente o 'plugin' do depurador jquery se estiver a usar o chrome: https://chrome.google.com/webstore/detail/jquery-debugger/dbhhnnnpaeobfddmlalhnehgclcmjimi?hl=en

 0
Author: Marquinho Peli, 2016-08-15 15:32:47

Para verificar eventos num elemento:

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

Note que isto só funcionará com os responsáveis directos por eventos, se estiver a usar o $(document).on ("event-name"," jq-selector", function () {//logic }), irá querer ver a função getEvents no fundo desta resposta

Por exemplo:

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

Ou

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

Exemplo Completo:

<html>
    <head>
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js" type="text/javascript"></script>
        <script>
            $(function() {
                $("#textDiv").click(function() {
                    //Event Handling
                });
                var events = $._data(document.getElementById('textDiv'), "events");
                var hasEvents = (events != null);
            });
        </script>
    </head>
    <body>
        <div id="textDiv">Text</div>
    </body>
</html>

Uma forma mais completa de verificar, que inclui ouvintes dinâmicos, instalado com $(documento).em

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

Uso de exemplo:

getEvents($('#myElemId')[0])
 0
Author: Tom G, 2018-08-30 15:39:11