Wie können Sie in jQuery Ereignisse an dynamische HTML-Elemente anhängen?

Angenommen, ich habe einen jQuery-Code, der einen Event-Handler an alle Elemente mit der class “myclass” anhängt. Beispielsweise:

$(function(){ $(".myclass").click( function() { // do something }); }); 

Und mein HTML könnte wie folgt aussehen:

 test1 test2 test3 

Das funktioniert ohne Probleme. Überlegen Sie jedoch, ob die “myclass” -Elemente zu einem späteren Zeitpunkt auf die Seite geschrieben wurden.

Beispielsweise:

 create link dynamically  $(function(){ $("#anchor1").click( function() { $("#anchor1").append('test4'); }); });  

In diesem Fall wird der Link “test4” erstellt, wenn ein Benutzer auf einen # Anker1 klickt.

Dem Link “test4” ist der click () – Handler nicht zugeordnet, obwohl er class = “myclass” hat.

Irgendeine Idee, wie ich das beheben kann?

Grundsätzlich möchte ich den click () – Handler einmal schreiben und sowohl auf Inhalte anwenden, die beim Laden der Seite vorhanden sind, als auch auf Inhalte, die später über Ajax / DHTML eingefügt werden.

Ich füge eine neue Antwort hinzu, um Änderungen in späteren jQuery-Versionen widerzuspiegeln. Die .live () -Methode ist seit jQuery 1.7 veraltet.

Von http://api.jquery.com/live/

Ab jQuery 1.7 ist die .live () -Methode veraltet. Verwenden Sie .on (), um Ereignishandler anzuhängen. Benutzer älterer Versionen von jQuery sollten .delegate () anstelle von .live () verwenden.

Für jQuery 1.7+ können Sie einen Ereignishandler an ein übergeordnetes Element anhängen, indem Sie .on () verwenden, und den a-Selektor in Kombination mit ‘myclass’ als Argument übergeben.

Siehe http://api.jquery.com/on/

Also statt …

 $(".myclass").click( function() { // do something }); 

Du kannst schreiben…

 $('body').on('click', 'a.myclass', function() { // do something }); 

Dies funktioniert für alle Tags mit ‘myclass’ im Body, ob bereits vorhanden oder dynamisch später hinzugefügt.

Das body-Tag wird hier verwendet, da das Beispiel kein näheres statisches umgebendes Tag hatte, aber jedes übergeordnete Tag, das beim Aufruf der .on-Methode vorhanden ist, funktioniert. Zum Beispiel würde ein UL-Tag für eine Liste, der dynamische Elemente hinzugefügt werden, wie folgt aussehen:

 $('ul').on('click', 'li', function() { alert( $(this).text() ); }); 

Solange das ul-Tag existiert, wird dies funktionieren (es müssen noch keine li-Elemente existieren).

Manchmal reicht das nicht (die Antwort mit der höchsten Wahl) :

 $('body').on('click', 'a.myclass', function() { // do something }); 

Dies kann ein Problem sein, weil die Order Event Handler ausgetriggers werden. Wenn Sie dies tun, aber es verursacht Probleme aufgrund der Reihenfolge, in der es behandelt wird. Sie können das immer in eine function einbinden, die den Listener beim Auffrischen “auffrischt”.

Beispielsweise:

 function RefreshSomeEventListener() { // Remove handler from existing elements $("#wrapper .specific-selector").off(); // Re-add event handler for all matching elements $("#wrapper .specific-selector").on("click", function() { // Handle event. } } 

Da es sich um eine function handelt, rufe ich sie, wenn ich meinen Hörer auf diese Weise einrichte, normalerweise in Dokument bereit:

 $(document).ready(function() { // Other ready commands / code // Call our function to setup initial listening RefreshSomeEventListener(); }); 

Wenn Sie dann ein dynamisch hinzugefügtes Element hinzufügen, rufen Sie diese Methode erneut auf:

 function SomeMethodThatAddsElement() { // Some code / AJAX / whatever.. Adding element dynamically // Refresh our listener, so the new element is taken into account RefreshSomeEventListener(); } 

Hoffentlich hilft das!

Grüße,

Nach jQuery 1.7 sind die bevorzugten Methoden .on () und .off ()

Seans Antwort zeigt ein Beispiel.

Jetzt veraltet:

Verwenden Sie die jQuery-functionen .live() und .die() . Verfügbar in jQuery 1.3.x

Aus den Dokumenten:

So zeigen Sie den Text jedes Absatzes bei jedem Klicken in einer Warnmeldung an:

 $("p").live("click", function(){ alert( $(this).text() ); }); 

Das LiveQuery- Plugin erledigt dies und unterstützt weitere Ereignisse.

Wenn Sie dem DOM einen Haufen von Ankern hinzufügen, schauen Sie stattdessen in die Ereignisdelegierung.

Hier ist ein einfaches Beispiel:

 $('#somecontainer').click(function(e) { var $target = $(e.target); if ($target.hasClass("myclass")) { // do something } }); 

Bindet einen Handler an ein Ereignis (wie Klick) für alle aktuellen und zukünftigen übereinstimmenden Elemente. Kann auch benutzerdefinierte Ereignisse binden.

Link Text

 $(function(){ $(".myclass").live("click", function() { // do something }); }); 

Sie können ein einzelnes Klickereignis für alle Elemente an eine Seite binden, unabhängig davon, ob sie bereits auf dieser Seite sind oder ob sie zu einem zukünftigen Zeitpunkt eintreffen:

 $(document).bind('click', function (e) { var target = $(e.target); if (target.is('.myclass')) { e.preventDefault(); // if you want to cancel the event flow // do something } else if (target.is('.myotherclass')) { e.preventDefault(); // do something else } }); 

Benutze es für eine Weile. Klappt wunderbar.

In jQuery 1.7 und höher wird empfohlen, .on() anstelle von bind oder einer anderen Ereignisdelegierungsmethode zu verwenden, aber .bind() funktioniert weiterhin.

Wenn Sie auf jQuery 1.3+ dann verwenden. Leben()

Bindet einen Handler an ein Ereignis (wie Klick) für alle aktuellen und zukünftigen übereinstimmenden Elemente. Kann auch benutzerdefinierte Ereignisse binden.

Sie möchten die function live() verwenden. Siehe die Dokumentation .

Beispielsweise:

 $("#anchor1").live("click", function() { $("#anchor1").append('test4'); });