it-swarm.com.de

Mit einem Objekt registrierte jQuery-Find-Ereignishandler

Ich muss herausfinden, welche Ereignishandler für ein Objekt registriert sind.

Zum Beispiel:

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

$("#el") hat click und mouseover registriert.

Gibt es eine Funktion, die dies herausfindet und möglicherweise die Event-Handler durchläuft?

Wenn es für ein jQuery-Objekt mit geeigneten Methoden nicht möglich ist, ist es für ein einfaches DOM-Objekt möglich?

528
ages04

Ab jQuery 1.8 sind die Ereignisdaten nicht mehr über die "öffentliche API" für Daten verfügbar. Lesen Sie diesen jQuery-Blog-Beitrag . Sie sollten dies jetzt stattdessen verwenden:

jQuery._data( elem, "events" );

elem sollte ein HTML-Element sein, kein jQuery-Objekt oder ein Selektor.

Bitte beachten Sie, dass dies eine interne, "private" Struktur ist und nicht geändert werden sollte. Verwenden Sie dies nur zu Debugging-Zwecken.

In älteren jQuery-Versionen müssen Sie möglicherweise die alte Methode verwenden:

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

Sie können dies tun, indem Sie die Ereignisse (ab jQuery 1.8+) wie folgt crawlen:

$.each($._data($("#id")[0], "events"), function(i, event) {
  // i is the event type, like "click"
  $.each(event, function(j, h) {
    // h.handler is the function being called
  });
});

Hier ist ein Beispiel, mit dem Sie spielen können:

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

  $.each($._data($("#el")[0], "events"), function(i, event) {
    output(i);
    $.each(event, function(j, h) {
        output("- " + h.handler);
    });
  });
});

function output(text) {
    $("#output").html(function(i, h) {
        return h + text + "<br />";
    });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="el">Test</div>
<code>
    <span id="output"></span>
</code>
79
Nick Craver

Ab jQuery 1.8 funktioniert dies nicht mehr, da die internen Daten in einem anderen Objekt abgelegt werden.

Die letzte inoffizielle (aber auch in früheren Versionen, zumindest in 1.7.2) Möglichkeit, dies jetzt zu tun, ist - $._data(element, "events")

Der Unterstrich ("_") macht hier den Unterschied. Intern ruft es $.data(element, name, null, true) auf, der letzte (vierte) Parameter ist ein interner ("pvt").

35
PhistucK

Schamloser Stecker, aber Sie können findHandlerJS verwenden

Um es zu verwenden, müssen Sie nur findHandlersJS (oder einfach roher Javascript-Code in das Konsolenfenster von Chrome kopieren und einfügen) und den Ereignistyp und einen JQuery-Selektor für die Elemente angeben, die Sie sind interessiert an.

Für Ihr Beispiel könnten Sie schnell die Ereignishandler finden, die Sie durch Ausführen erwähnt haben

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

Folgendes wird zurückgegeben:

  • element
    Das tatsächliche Element, in dem der Ereignishandler registriert wurde
  • veranstaltungen
    Array mit Informationen zu den jquery-Ereignishandlern für den Ereignistyp, an dem wir interessiert sind (z. B. Klicken, Ändern usw.)
    • handler
      Aktuelle Ereignishandlermethode, die Sie anzeigen können, indem Sie mit der rechten Maustaste darauf klicken und Funktionsdefinition anzeigen auswählen
    • wähler
      Der Selektor für delegierte Ereignisse. Für direkte Ereignisse ist es leer.
    • ziele
      Liste mit den Elementen, auf die diese Ereignisbehandlungsroutine abzielt. Beispielsweise listet diese Eigenschaft für einen delegierten Ereignishandler, der im Dokumentobjekt registriert ist und auf alle Schaltflächen auf einer Seite abzielt, alle Schaltflächen auf der Seite auf. Sie können sie mit der Maus bewegen und sie in Chrom hervorheben.

Sie können es versuchen hier

32
Rui

Ich benutze das eventbug Plugin, um den Fehler zu beheben.

12
Anton

Ich habe beide Lösungen von @jps zu einer Funktion kombiniert:

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

Beachten Sie jedoch, dass diese Funktion nur Ereignisse zurückgeben kann, die mit jQuery selbst festgelegt wurden.

9
algorhythm

Ab Version 1.9 gibt es keine dokumentierte Möglichkeit, die Ereignisse abzurufen, außer das Migrate-Plugin zum Wiederherstellen des alten Verhaltens zu verwenden. Sie könnten die _.data () -Methode als jps-Erwähnung verwenden, aber das ist eine interne Methode. Tun Sie einfach das Richtige und verwenden Sie das Migrate-Plugin, wenn Sie diese Funktionalität benötigen.

Aus der jQuery-Dokumentation zu .data("events")

Vor 1.9 konnte mit .data ("events") die undokumentierte interne Ereignisdatenstruktur von jQuery für ein Element abgerufen werden, wenn kein anderer Code ein Datenelement mit dem Namen "events" definiert hatte. Dieser Sonderfall wurde in 1.9 entfernt. Es gibt keine öffentliche Schnittstelle zum Abrufen dieser internen Datenstruktur, und sie ist nicht dokumentiert. Das jQuery Migrate-Plugin stellt dieses Verhalten jedoch für Code wieder her, der davon abhängt.

5
oligofren

Ich habe einen benutzerdefinierten jQuery-Selektor erstellt, der sowohl den Cache von jQuery mit zugewiesenen Ereignishandlern als auch mit Elementen vergleicht, die die native Methode zum Hinzufügen verwenden:

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

Beispiel:

$(":event(click)")

Dies gibt Elemente zurück, an die ein Klick-Handler angehängt ist.

3
Erutan409

In einem modernen Browser mit ECMAScript 5.1/Array.prototype.map können Sie auch verwenden

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

in Ihrer Browserkonsole, die die Quelle der Handler ausgibt, durch Kommas getrennt. Nützlich, um einen Blick darauf zu werfen, was bei einem bestimmten Ereignis alles läuft.

2
Jesan Fafon

m nach Ereignissen für ein Element zu suchen:

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

Beachten Sie, dass dies nur mit direkten Event-Handlern funktioniert, wenn Sie $ (document) .on ("event-name", "jq-selector", function () {// logic}) verwenden Die Funktion getEvents steht am Ende dieser Antwort

Zum Beispiel:

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

oder

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

Vollständiges Beispiel:

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

Eine vollständigere Möglichkeit zur Überprüfung, einschließlich dynamischer Listener, die mit $ (document) .on installiert wurden.

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

Anwendungsbeispiel:

getEvents($('#myElemId')[0])
2
Tom G

Ich muss sagen, dass viele der Antworten interessant sind, aber kürzlich hatte ich ein ähnliches Problem und die Lösung war extrem einfach, indem ich den DOM-Weg eingeschlagen habe. Es ist anders, weil Sie nicht iterieren, sondern direkt auf das gewünschte Ereignis zielen. Im Folgenden werde ich eine allgemeinere Antwort geben.

Ich hatte ein Bild in einer Reihe:

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

Und an dieses Bild war ein Click-Event-Handler angehängt:

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

Meine Absicht war es, den anklickbaren Bereich auf die gesamte Zeile auszudehnen, so dass ich zuerst alle Bilder und relativen Zeilen bekam:

tableNode.find("img.folder").each(function () {
  var tr;

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

Jetzt habe ich in der actual anwer -Zeile wie folgt eine Antwort auf die ursprüngliche Frage gegeben:

tr.click(this.onclick);

Daher habe ich den Ereignishandler direkt aus dem DOM-Element abgerufen und in den Ereignishandler jQuery click eingefügt. Klappt wunderbar.

Nun zum allgemeinen Fall. In den alten Tagen vor jQuery konnten Sie alle Ereignisse an ein Objekt mit zwei einfachen, aber leistungsstarken Funktionen anhängen, die uns Sterblichen von 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;
      }
    }
  });
}
1
pid

Versuchen Sie das Plug-in für den JQuery-Debugger, wenn Sie Chrome verwenden: https://chrome.google.com/webstore/detail/jquery-debugger/dbhhnnnpaeobfddmlalhnehgclcmjimi?hl=de

1
Marquinho Peli

Ereignisse können abgerufen werden mit:

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

oder jQuery 1.8+:

jQuery._data(elem, 'events');

Hinweis: Ereignisse, die mit $('selector').live('event', handler) begrenzt wurden, können mit folgendem Befehl abgerufen werden:

jQuery(document).data('events')
1
R. Oosterholt

Eine andere Möglichkeit besteht darin, einfach jQuery zu verwenden, um das Element zu erfassen, und dann das eigentliche Javascript durchzugehen, um die Ereignishandler abzurufen, festzulegen und damit zu spielen. Zum Beispiel:

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