Ich versuche, diesen besonderen Unterschied zwischen den direkten und delegierten Ereignishandlern mithilfe der Methode jQuery .on () zu verstehen . Insbesondere der letzte Satz in diesem Absatz:
Wenn a angegeben
selector
ist, wird der Ereignishandler als delegiert bezeichnet . Der Handler wird nicht aufgerufen, wenn das Ereignis direkt auf dem gebundenen Element auftritt, sondern nur für Nachkommen (innere Elemente), die dem Selektor entsprechen. jQuery sprudelt das Ereignis vom Ereignisziel bis zu dem Element, an das der Handler angehängt ist (dh vom innersten zum äußersten Element), und führt den Handler für alle Elemente entlang dieses Pfads aus, die dem Selektor entsprechen.
Was bedeutet "führt den Handler für Elemente aus"? Ich habe eine Testseite erstellt , um mit dem Konzept zu experimentieren. Beide folgenden Konstrukte führen jedoch zum gleichen Verhalten:
$("div#target span.green").on("click", function() {
alert($(this).attr("class") + " is clicked");
});
oder,
$("div#target").on("click", "span.green", function() {
alert($(this).attr("class") + " is clicked");
});
Vielleicht könnte sich jemand auf ein anderes Beispiel beziehen, um diesen Punkt zu verdeutlichen? Vielen Dank.
Antworten:
Fall 1 (direkt):
== Hey! Ich möchte, dass jedes span.green in div # target zuhört: Wenn Sie darauf klicken, machen Sie X.
Fall 2 (delegiert):
== Hey, div # Ziel! Wenn eines Ihrer untergeordneten Elemente, die "span.green" sind, angeklickt wird, machen Sie X mit ihnen.
Mit anderen Worten...
In Fall 1 wurde jeder dieser Bereiche einzeln Anweisungen gegeben. Wenn neue Bereiche erstellt werden, haben sie die Anweisung nicht gehört und reagieren nicht auf Klicks. Jede Spanne ist direkt für ihre eigenen Ereignisse verantwortlich.
In Fall 2 hat nur der Container die Anweisung erhalten; Es ist dafür verantwortlich, Klicks im Namen seiner untergeordneten Elemente zu bemerken . Die Arbeit, Ereignisse zu fangen, wurde delegiert . Dies bedeutet auch, dass die Anweisung für untergeordnete Elemente ausgeführt wird, die in Zukunft erstellt werden.
quelle
on()
zwei Argumente zulassen, wenn das so ziemlich das gleiche wäre wie die Verwendungclick()
?e.target
ist das ursprüngliche Ziel des Klickereignisses (kann ein untergeordneter Knoten sein, wenn untergeordnete Knoten vorhanden sindspan.green
). Im Handler sollten Sie diethis
Referenz verwenden. Sehen Sie diese Geige .Der erste Weg
$("div#target span.green").on()
bindet einen Klick-Handler direkt an die Spanne (n), die zum Zeitpunkt der Ausführung des Codes mit dem Selektor übereinstimmen. Dies bedeutet, dass andere Bereiche, die später hinzugefügt werden (oder deren Klasse entsprechend geändert wird), diese verpasst haben und keinen Klick-Handler haben. Wenn Sie später die "grüne" Klasse aus einem der Bereiche entfernen, wird der Klick-Handler weiterhin ausgeführt. JQuery verfolgt nicht, wie der Handler zugewiesen wurde, und prüft, ob der Selektor noch übereinstimmt.Die zweite Möglichkeit besteht darin
$("div#target").on()
, einen Klick-Handler an die übereinstimmenden Divs zu binden (dies ist wiederum gegen diejenigen, die in diesem Moment übereinstimmen). Wenn jedoch irgendwo im Div ein Klick auftritt, wird die Handler-Funktion nur ausgeführt, wenn der Klick erfolgt trat nicht nur im div auf, sondern in einem.on()
untergeordneten Element, das dem Selektor im zweiten Parameter "span.green" entspricht. Auf diese Weise spielt es keine Rolle, wann diese untergeordneten Bereiche erstellt wurden. Wenn Sie darauf klicken, wird der Handler weiterhin ausgeführt.Bei einer Seite, die ihren Inhalt nicht dynamisch hinzufügt oder ändert, werden Sie keinen Unterschied zwischen den beiden Methoden feststellen. Wenn Sie zusätzliche untergeordnete Elemente dynamisch hinzufügen, müssen Sie sich nach der zweiten Syntax keine Gedanken mehr über das Zuweisen von Klick-Handlern machen, da Sie dies bereits einmal auf dem übergeordneten Element getan haben.
quelle
Die Erklärung von N3dst4 ist perfekt. Auf dieser Grundlage können wir davon ausgehen, dass sich alle untergeordneten Elemente im Körper befinden. Daher müssen wir nur Folgendes verwenden:
Es funktioniert mit direkten oder delegierten Ereignissen.
quelle
$('body').on()
Delegierung von.element
genauso verhalten wie die native Delegierungdocument.body.addEventHandler()
mit einemif (Event.target.className.matches(/\belement\b/))
im Rückruf. Aufgrund des$.proxy
Overheads kann es bei der Abfrage etwas langsamer sein, aber zitieren Sie mich nicht dazu.Tangential zum OP, aber das Konzept, das mir geholfen hat, die Verwirrung mit dieser Funktion zu lösen, ist, dass die gebundenen Elemente Eltern der ausgewählten Elemente sein müssen .
.on
..on()
.Die Delegierung funktioniert nicht wie .find () und wählt eine Teilmenge der gebundenen Elemente aus. Der Selektor gilt nur für strenge untergeordnete Elemente.
ist ganz anders als
Insbesondere um die Vorteile zu nutzen, die @ N3dst4 mit "Elementen, die in Zukunft erstellt werden" angibt, muss das gebundene Element ein permanentes übergeordnetes Element sein . Dann können die ausgewählten Kinder kommen und gehen.
BEARBEITEN
Checkliste, warum delegiert
.on
nicht funktioniertKnifflige Gründe, warum
$('.bound').on('event', '.selected', some_function)
möglicherweise nicht funktionieren:.on()
.stopPropagation()
.(Auslassen weniger kniffliger Gründe wie eines falsch geschriebenen Selektors.)
quelle
Ich habe einen Beitrag mit einem Vergleich von direkten Ereignissen geschrieben und delegiert. Ich vergleiche reines js, aber es hat die gleiche Bedeutung für jquery, die es nur einkapselt.
Die Schlussfolgerung lautet, dass die delegierte Ereignisbehandlung für eine dynamische DOM-Struktur vorgesehen ist, bei der gebundene Elemente erstellt werden können, während der Benutzer mit der Seite interagiert (keine erneuten Bindungen erforderlich), und dass die direkte Ereignisbehandlung für statische DOM-Elemente gilt, wenn wir wissen, dass sich die Struktur nicht ändert.
Für weitere Informationen und einen vollständigen Vergleich - http://maciejsikora.com/standard-events-vs-event-delegation/
Die Verwendung von immer delegierten Handlern, von denen ich sehe, dass sie derzeit sehr trendy sind, ist nicht der richtige Weg. Viele Programmierer verwenden sie, weil "sie verwendet werden sollten". In Wahrheit sind direkte Ereignishandler für bestimmte Situationen besser und die Wahl, welche Methode verwendet werden soll durch Kenntnis der Unterschiede.
quelle