En jQuery, comment attacher des événements à des éléments html dynamiques? [dupliquer]
cette question a déjà une réponse ici:
supposons que j'ai un code jQuery qui attache un gestionnaire d'événements à tous les éléments de la classe "myclass". Par exemple:
$(function(){
$(".myclass").click( function() {
// do something
});
});
et mon html pourrait être le suivant:
<a class="myclass" href="#">test1</a>
<a class="myclass" href="#">test2</a>
<a class="myclass" href="#">test3</a>
ça marche sans problème. Cependant, pensez à savoir si les éléments" myclass " ont été écrits sur la page à une date ultérieure.
par exemple:
<a id="anchor1" href="#">create link dynamically</a>
<script type="text/javascript">
$(function(){
$("#anchor1").click( function() {
$("#anchor1").append('<a class="myclass" href="#">test4</a>');
});
});
</script>
dans ce cas, le lien" test4 " est créé lorsqu'un utilisateur clique sur une ancre#1.
le lien"test4"n'a pas le handler click() qui lui est associé, même s'il a class= "myclass".
une idée de comment je peux réparer ça?
fondamentalement, je voudrais écrire le handler click() une fois et le faire appliquer à la fois au contenu présent au chargement de page, et au contenu apporté plus tard via Ajax/DHTML.
8 réponses
j'ajoute une nouvelle réponse pour refléter les changements dans les versions ultérieures de jQuery. Le. la méthode live () est dépréciée à partir de jQuery 1.7.
de http://api.jquery.com/live /
de jQuery 1.7, l' .la méthode live () est dépréciée. Utiliser. sur() pour attacher les gestionnaires d'événements. Les utilisateurs des anciennes versions de jQuery devraient utiliser .délégué() de préférence .vivre.)(
pour jQuery 1.7 + you peut attacher un handler d'événement à un élément parent en utilisant .sur () et passer de l'un sélecteur combiné avec "myclass" comme argument.
voir http://api.jquery.com/on /
donc à la place...
$(".myclass").click( function() {
// do something
});
vous pouvez écrire...
$('body').on('click', 'a.myclass', function() {
// do something
});
cela fonctionnera pour toutes les étiquettes a avec 'myclass' dans le corps, qu'elles soient déjà présentes ou dynamiquement ajoutées plus tard.
le la balise body est utilisée ici car l'exemple n'a pas de balise d'environnement statique plus proche, mais n'importe quelle balise parent qui existe quand le .sur appel de méthode se produit fonctionnera. Par exemple, une étiquette ul pour une liste qui aura des éléments dynamiques ajoutés ressemblera à ceci:
$('ul').on('click', 'li', function() {
alert( $(this).text() );
});
aussi longtemps Que la balise ul existe cela fonctionne (pas de li éléments existent encore).
parfois faire cela (la réponse la plus votée) n'est pas toujours suffisant:
$('body').on('click', 'a.myclass', function() {
// do something
});
Cela peut être un problème en raison de l'ordre des gestionnaires d'événements sont déclenchés. Si vous vous trouvez à faire cela, mais il provoque des problèmes en raison de l'ordre dans lequel il est traité.. Vous pouvez toujours envelopper cela dans une fonction, qui, lorsqu'elle est appelée "rafraîchit" l'auditeur.
par exemple:
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.
}
}
parce qu'il est une fonction, chaque fois que je mets en place mon auditeur de cette façon, je l'appelle typiquement sur Document ready:
$(document).ready(function() {
// Other ready commands / code
// Call our function to setup initial listening
RefreshSomeEventListener();
});
ensuite, chaque fois que vous ajoutez un élément dynamiquement ajouté, appelez cette méthode à nouveau:
function SomeMethodThatAddsElement() {
// Some code / AJAX / whatever.. Adding element dynamically
// Refresh our listener, so the new element is taken into account
RefreshSomeEventListener();
}
espérons que cela aide!
Cordialement,
après jQuery 1.7 les méthodes préférées sont .sur() et .off ()
de Sean réponse montre un exemple.
Maintenant Déprécié:
utiliser les fonctions jQuery
.live()
et.die()
. Disponible en jQuery 1.3.xdu docs:
pour afficher le texte de chaque paragraphe dans un boîte d'alerte chaque fois qu'il est cliqué:
$("p").live("click", function(){ alert( $(this).text() ); });
aussi, le livequery plugin fait cela et a le support pour plus d'événements.
si vous ajoutez une pile d'ancres au DOM, regardez dans la délégation d'événement à la place.
voici un exemple simple:
$('#somecontainer').click(function(e) {
var $target = $(e.target);
if ($target.hasClass("myclass")) {
// do something
}
});
lie un gestionnaire à un événement (comme un clic) pour tous les éléments actuels et futurs. Peut aussi lier des événements personnalisés.
$(function(){
$(".myclass").live("click", function() {
// do something
});
});
vous pouvez lier un événement de clic simple à une page pour tous les éléments, peu importe s'ils sont déjà sur cette page ou s'ils arriveront à un moment futur, comme cela:
$(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
}
});
l'utilise depuis un moment. Fonctionne comme un charme.
dans jQuery 1.7 et plus tard, il est recommandé d'utiliser .on()
à la place de bind ou toute autre méthode de délégation d'événement, mais .bind()
fonctionne toujours.
vous voulez utiliser la fonction live()
. Voir les docs .
par exemple:
$("#anchor1").live("click", function() {
$("#anchor1").append('<a class="myclass" href="#">test4</a>');
});