jQuery-Funktion, die nicht an neu hinzugefügte dom-Elemente gebunden ist

75

Hier ist index.html:

<head>
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
  <script type="text/javascript">

    $(document).ready(function() {
      $('.btn_test').click(function() { alert('test'); });
    });

    function add(){
      $('body').append('<a href=\'javascript:;\' class=\'btn_test\'>test</a>');
    }

  </script>
</head>
<body>
  <a href="javascript:;" class="btn_test">test1</a>
  <a href="javascript:;" onclick="add()">add</a>
</body>

Wenn ich auf den test1Link klicke, wird angezeigt alert('test'), aber wenn ich auf den addLink klicke und dann auf klicke test, wird nichts angezeigt.

Könnten Sie es erklären?

Ralsk28
quelle
4
und 10000 Leute haben gerade die gleiche Antwort geschrieben
Amir Raminfar
9
@Bad Anzeigename: Dann beheben Sie es und seien Sie kein Idiot.
scrappedcola

Antworten:

213

Für Benutzer, die nach 2011 zu dieser Frage kommen, gibt es einen neuen geeigneten Weg, dies zu tun:

$(document).on('click', '.btn_test', function() { alert('test'); });

Dies ist ab jQuery 1.7.

Weitere Informationen finden Sie unter Direkte und delegierte Ereignisse

Moshe Katz
quelle
2
Ich wünschte, ich könnte die Antwort als "Akzeptierte Antwort" auswählen. Danke, dass du meinen (verbleibenden) Tag gerettet hast!
Sohaiby
1
Ich habe mein gesamtes Projekt immer wieder entbunden () und neu gebunden, bevor ich das gesehen habe. Wo ist der Typ, der das gefragt hat? Mann, akzeptiere es.
Unrealist
Faszinierend und cool! Vielen Dank, dass Sie diese Klarstellung hinzugefügt haben. Ein ärgerliches Problem für mich wurde behoben.
Tonejac
Sie sollten hinzufügen, dass der richtige Weg, dies zu lösen, darin besteht, den Parameter "Selektor" hinzuzufügen. Ich habe es nach dem Lesen des Links herausgefunden, aber nicht wegen Ihrer Antwort. Ich bin immer noch dankbar :) @Moshe Katz
villancikos
$ (document) ist in Ordnung, aber für eine optimale Leistung ist es besser, stattdessen $ ("# element") oder $ (". class") zu verwenden - wobei das Element oder die Klasse bereits im dom vorhanden ist. Anstatt dass jquery das gesamte Dokument überwacht, wird nur das #element oder die .class überwacht.
Eric Kigathi
34

Sie müssen einen "Live" -Klick-Listener verwenden, da anfangs nur das einzelne Element vorhanden ist.

$('.btn_test').live("click", function() { 
   alert('test'); 
});

Update: Da Live veraltet ist, sollten Sie "on ()" verwenden:

$(".btn_test").on("click", function(){ 
   alert("test");
});

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

Doug Molineux
quelle
3
Ja, zur Verdeutlichung - liveist ein dynamischer Handler mit später Bindung, der an Elemente angehängt werden kann, die dem DOM hinzugefügt wurden, nachdem der Handler deklariert wurde. Weitere Informationen finden Sie in dieser Dokumentation .
chrisf
2
Eine andere Möglichkeit, dies anzugeben, lautet: .click()Gilt nur für Objekte, die beim Laden der Seite vorhanden sind, gilt jedoch .live()für alle Objekte, die jetzt vorhanden sind oder in Zukunft erstellt werden.
George Cummins
Ich habe eine neue Frage, wie kann ich Live-Methode mit diesem -> Steamdev.com/zclip
Ralsk28
1
@ Ralsk28: Wenn diese Antwort dir geholfen hat, kannst du Pete belohnen, indem du die Antwort abstimmst und auf den Scheck klickst, um sie zu akzeptieren. Dies wird auch zukünftigen Besuchern der Website helfen, Lösungen für ihre eigenen Probleme zu finden.
George Cummins
1
live () ist jetzt veraltet, nicht wahr? Was ist die Alternative?
Chris Job
15

Ich habe das gleiche Problem wie die Frage, dass ich kurz davor war, an meinen Haaren zu ziehen, dann habe ich die Lösung gefunden. Ich habe eine andere Syntax verwendet

$(".innerImage").on("click", function(){ 
alert("test");
});

es hat bei mir nicht funktioniert (innerImage wird dynamisch dom erstellt) Jetzt benutze ich

$(document).on('click', '.innerImage', function() { alert('test'); });

http://jsfiddle.net/SDJEp/2/

danke @Moshe Katz

Umer Farooq
quelle
8

.click bindet an das, was derzeit für jQuery sichtbar ist. Sie müssen .live verwenden:

$('.btn_test').live('click', function() { alert('test'); });
CassOnMars
quelle
Ich denke, es ist die beste Antwort auf dieses Problem.
7

Verwenden Sie stattdessen Jquery live . Hier ist die Hilfeseite dafür http://api.jquery.com/live/

$('.btn_test').live(function() { alert('test'); });

Bearbeiten: live()ist veraltet und sollte on()stattdessen verwendet werden.

$(".btn_test").on("click", function(){ 
   alert("test");
});
Amir Raminfar
quelle
.live () ist veraltet. Verwenden Sie .on ().
Freeworlder
6
@silkfield Ich habe meine Antwort aktualisiert. Aber beim nächsten Mal schlagen Sie bitte eine Bearbeitung vor, anstatt abzustimmen. SO ist ein Community-Frage-Antwort-Forum, in dem wir uns alle verbessern können.
Amir Raminfar
3

Dies liegt daran, dass das Klickereignis zum Zeitpunkt der Bindung nur an das vorhandene Element gebunden ist. Sie müssen Live oder Delegate verwenden, um das Ereignis an vorhandene und zukünftige Elemente auf der Seite zu binden.

$('.btn_test').live("click", function() { alert('test'); });

Jquery Live

verschrottete Cola
quelle
2

Sie benötigen einen Live-Listener anstelle eines Klicks:

$('.btn_test').live('click', function() { 
   alert('test'); 
});

Der Grund dafür ist, dass der clickListener dem Listener nur Elemente zuweist, wenn die Seite geladen wird. Alle neu hinzugefügten Elemente enthalten diesen Listener nicht. Live fügt den Klick-Listener dem Element hinzu, wenn die Seite geladen wird und wenn sie anschließend hinzugefügt werden

locrizak
quelle
1

Wenn das Dokument geladen wird, fügen Sie jeder übereinstimmenden Klasse Ereignis-Listener hinzu, um auf das Klickereignis für diese Elemente zu warten. Der gleiche Listener wird nicht automatisch zu Elementen hinzugefügt, die Sie später zum Dom hinzufügen.

shanethehat
quelle
1

Weil das Ereignis an jedes übereinstimmende Element im Dokument gebunden gebunden ist. Alle neu hinzugefügten Elemente sind NICHT automatisch mit denselben Ereignissen verknüpft.

Sie müssen das Ereignis nach dem Hinzufügen manuell an ein neues Element binden oder den Live-Listener verwenden.

Neil N.
quelle
1
$('.btn_test').click

fügt den Handler für Elemente hinzu, die auf der Seite verfügbar sind (zu diesem Zeitpunkt existiert 'test' nicht!)

Sie müssen entweder manuell einen Klick-Handler für dieses Element hinzufügen, wenn Sie anhängen, oder einen liveEreignishandler verwenden, der für jedes Element funktioniert, auch wenn Sie es später erstellen.

$('.btn_test').live(function() { alert('test'); });
Karoly Horvath
quelle
1

Nach jquery 1.7 kann die Methode verwendet werden und es funktioniert wirklich gut

<!DOCTYPE html>
<html>
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js">
    </script>
<script>
    $(document).ready(function(){
      $("p").on("click",function(){
       alert("The paragraph was clicked.");
       $("body").append("<p id='new'>Now click on this paragraph</p>");
    });
    $(document).on("click","#new",function(){
       alert("On really works.");
      });
    });
</script>
</head>
<body>
    <p>Click this paragraph.</p>
</body>
</html>

sehen Sie es in Aktion http://jsfiddle.net/rahulchaturvedie/CzR6n/

Rahul
quelle
0

Oder führen Sie einfach das Skript am Ende Ihrer Seite aus

Enigmax
quelle
0

Sie müssen eine geeignete Tastenklickfunktion hinzufügen, um ein korrektes Ergebnis zu erzielen

$("#btn1").live(function() { alert("test"); });
Salman Ashraf
quelle