jQuery trova gestori di eventi registrati con un object

Devo trovare quali gestori di eventi sono registrati su un object.

Per esempio:

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

$("#el") ha registrato il click e il mouseover .

Esiste una funzione per scoprirlo e probabilmente iterare sui gestori di eventi?

Se non è ansible su un object jQuery attraverso metodi appropriati, è ansible su un object DOM semplice?

A partire da jQuery 1.8, i dati degli eventi non sono più disponibili dalla “API pubblica” per i dati. Leggi questo post sul blog di jQuery . Ora dovresti usare questo:

 jQuery._data( elem, "events" ); 

elem dovrebbe essere un elemento HTML, non un object jQuery o un selettore.

Si noti che questa è una struttura interna “privata” e non deve essere modificata. Usalo solo a scopo di debug.

Nelle versioni precedenti di jQuery, potresti dover utilizzare il vecchio metodo che è:

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

Puoi farlo in questo modo:

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

Se sei su jQuery 1.4+, questo avviserà l’evento e le funzioni ad esso associate:

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

Puoi giocarci su jsFiddle qui

Per jQuery 1.8+, questo non funzionerà più perché i dati interni sono collocati in un object diverso.

L’ultimo modo non ufficiale (ma funziona anche nelle versioni precedenti, almeno nella 1.7.2) ora è – $._data(element, "events")

Il carattere di sottolineatura (“_”) è ciò che fa la differenza qui. Internamente, chiama $.data(element, name, null, true) , l’ultimo (quarto) parametro è interno (“pvt”).

Plug senza vergogna, ma puoi usare findHandlerJS

Per utilizzarlo devi includere findHandlersJS (o semplicemente copiare e incollare il codice javascript raw nella finestra della console di chrome) e specificare il tipo di evento e un selettore jquery per gli elementi che ti interessano.

Per il tuo esempio potresti trovare rapidamente i gestori di eventi che hai menzionato facendo

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

Questo è ciò che viene restituito:

  • elemento
    L’elemento reale in cui è stato registrato il gestore eventi
  • eventi
    Matrice con informazioni sui gestori di eventi jquery per il tipo di evento a cui siamo interessati (ad esempio clic, modifica, ecc.)
    • gestore
      Metodo del gestore eventi effettivo che è ansible visualizzare facendo clic con il pulsante destro del mouse e selezionando Mostra definizione della funzione
    • selettore
      Il selettore fornito per eventi delegati. Sarà vuoto per eventi diretti.
    • obiettivi
      Elenca gli elementi che questo gestore di eventi ha come target. Ad esempio, per un gestore di eventi delegato registrato nell’object del documento e indirizza tutti i pulsanti in una pagina, questa proprietà elencherà tutti i pulsanti nella pagina. Puoi passare il mouse su di loro e vederli evidenziati in chrome.

Puoi provarlo qui

Io uso il plugin eventbug per firebug per questo scopo.

Ho combinato entrambe le soluzioni da @jps a una funzione:

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

Ma attenzione, questa funzione può solo restituire quegli eventi che sono stati impostati con jQuery stesso.

A partire dal 1.9 non esiste un modo documentato per recuperare gli eventi, oltre a utilizzare il plugin Migrate per ripristinare il vecchio comportamento. È ansible utilizzare il metodo _.data () come menzioni jps, ma questo è un metodo interno. Quindi, fai la cosa giusta e usa il plugin Migrate se hai bisogno di questa funzionalità.

Dalla documentazione di jQuery su .data("events")

Prima del 1.9, .data (“eventi”) poteva essere usato per recuperare la struttura di dati dell’evento interno non documentata di jQuery per un elemento se nessun altro codice aveva definito un elemento di dati con il nome “eventi”. Questo caso speciale è stato rimosso nel 1.9. Non esiste un’interfaccia pubblica per recuperare questa struttura di dati interna e rimane non documentata. Tuttavia, il plugin jQuery Migrate ripristina questo comportamento per il codice che dipende da esso.

In un browser moderno con ECMAScript 5.1 / Array.prototype.map , puoi anche utilizzare

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

nella tua console del browser, che stamperà la fonte dei gestori, delimitata da virgola. Utile per dare un’occhiata a ciò che è in esecuzione su un particolare evento.

Devo dire che molte delle risposte sono interessanti, ma recentemente ho avuto un problema simile e la soluzione è stata estremamente semplice andando in modo DOM. È diverso perché non si itera ma si punta direttamente all’evento di cui si ha bisogno, ma di seguito darò una risposta più generale.

Ho avuto un’immagine di fila:

 ...

E quell’immagine aveva un gestore di eventi click collegato ad esso:

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

La mia intenzione era quella di espandere l’area cliccabile all’intera riga, quindi ho prima ottenuto tutte le immagini e le righe relative:

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

Ora, nella linea attuale di anwer , ho semplicemente fatto come segue, dando una risposta alla domanda originale:

 tr.click(this.onclick); 

Quindi ho scaricato il gestore di eventi direttamente dall'elemento DOM e l'ho inserito nel gestore di eventi click jQuery. Funziona come un fascino.

Ora, nel caso generale. Nei vecchi giorni pre-jQuery si potevano ottenere tutti gli eventi collegati a un object con due funzioni semplici ma potenti regalate a noi mortali da 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; } } }); } 

Gli eventi possono essere recuperati utilizzando:

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

o jQuery 1.8+:

 jQuery._data(elem, 'events'); 

Nota: gli eventi limitati utilizzando $('selector').live('event', handler) possono essere recuperati utilizzando:

 jQuery(document).data('events') 

Ho creato un selettore jQuery personalizzato che controlla sia la cache di jQuery dei gestori di eventi assegnati sia gli elementi che utilizzano il metodo nativo per aggiungerli:

 (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); 

Esempio:

 $(":event(click)") 

Ciò restituirà elementi a cui è collegato un gestore di clic.

Un altro modo per farlo è usare jQuery per afferrare l’elemento, quindi passare attraverso Javascript reale per ottenere e impostare e giocare con i gestori di eventi. Per esempio:

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

Per verificare gli eventi su un elemento:

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

Nota che questo funzionerà solo con gestori di eventi diretti, se stai usando $ (document) .on (“nome-evento”, “jq-selector”, function () {// logic}), vorrai vedere il funzione getEvents in fondo a questa risposta

Per esempio:

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

o

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

Esempio completo:

       
Text

Un modo più completo per controllare, che include listener dinamici, installato con $ (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; } 

Esempio di utilizzo:

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