Question Dans 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 avec la classe "myclass". Par exemple:

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

Et mon html pourrait être comme suit:

<a class="myclass" href="#">test1</a>
<a class="myclass" href="#">test2</a>
<a class="myclass" href="#">test3</a>

Cela fonctionne sans problème. Cependant, vérifiez si les éléments "myclass" ont été écrits sur la page ultérieurement.

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 un # anchor1.

Le lien "test4" n'a pas le gestionnaire click () associé, même s'il a class = "myclass".

Une idée de comment je peux résoudre ce problème?

Fondamentalement, je voudrais écrire le gestionnaire de click () une fois et l'appliquer à la fois le contenu présent au chargement de la page, et le contenu apporté plus tard via Ajax / DHTML.


448
2017-08-31 19:29


origine


Réponses:


J'ajoute une nouvelle réponse pour refléter les modifications apportées aux versions ultérieures de jQuery. La méthode .live () est déconseillée à partir de jQuery 1.7.

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

À partir de jQuery 1.7, la méthode .live () est obsolète. Utilisez .on () pour attacher des gestionnaires d'événements. Les utilisateurs des anciennes versions de jQuery doivent utiliser .delegate () de préférence à .live ().

Pour jQuery 1.7+, vous pouvez associer un gestionnaire d'événement à un élément parent à l'aide de .on () et passer le sélecteur combiné à «myclass» en tant qu'argument.

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

Donc, au lieu de ...

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

Tu peux écrire...

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

Cela fonctionnera pour toutes les balises avec «myclass» dans le corps, qu'elles soient déjà présentes ou ajoutées ultérieurement.

La balise body est utilisée ici car l'exemple n'a pas de balise statique environnante plus proche, mais toute balise parent qui existe lors de l'appel de la méthode .on fonctionnera. Par exemple, une balise ul pour une liste qui aura des éléments dynamiques ajoutés ressemblera à ceci:

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

Tant que la balise ul existe, cela fonctionnera (aucun élément li n'existe encore).


760
2018-02-17 15:37



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 de déclenchement des gestionnaires d'événements. Si vous vous trouvez en train de faire cela, mais cela provoque des problèmes en raison de l'ordre dans lequel il est géré .. Vous pouvez toujours envelopper dans une fonction, que lorsque appelé "actualise" 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 que c'est une fonction, chaque fois que je configure mon auditeur de cette manière, je l'appelle généralement sur le document prêt:

$(document).ready(function() {
    // Other ready commands / code

    // Call our function to setup initial listening
    RefreshSomeEventListener();
});

Ensuite, chaque fois que vous ajoutez un élément ajouté dynamiquement, appelez à nouveau cette méthode:

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,


65
2017-07-15 20:28



Après jQuery 1.7, les méthodes préférées sont .sur() et .de() 

La réponse de Sean montre un exemple.

Maintenant déprécié:

Utilisez les fonctions jQuery .live() et .die(). Disponible en   jQuery 1.3.x

De la docs:

Pour afficher le texte de chaque paragraphe dans un     boîte d'alerte à chaque fois que vous cliquez dessus:

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

Également livequery le plugin le fait et a un support pour plus d'événements.


36
2017-08-31 19:30



Si vous ajoutez une pile d'ancres au DOM, recherchez plutôt la délégation d'événement.

Voici un exemple simple:

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

4
2017-08-31 19:39



Lie un gestionnaire à un événement (comme un clic) pour tous les éléments correspondants actuels et futurs. Peut également lier des événements personnalisés.

texte du lien

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

3
2017-08-31 19:32



Vous pouvez lier un événement de clic unique à une page pour tous les éléments, peu importe s'ils se trouvent déjà sur cette page ou s'ils arriveront plus tard, 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
   }
});

Je l'utilise depuis longtemps. Fonctionne comme un charme.

Dans jQuery 1.7 et versions ultérieures, il est recommandé d'utiliser .on() à la place de bind ou de toute autre méthode de délégation d'événement, mais .bind() fonctionne encore.


2
2018-03-29 03:09



Si vous êtes sur jQuery 1.3+ alors utilisez.vivre()

Lie un gestionnaire à un événement (comme   cliquez) pour tous les courants - et futurs -   élément correspondant. Peut aussi lier la coutume   événements.


1
2017-08-31 19:31



Vous voulez utiliser le live() fonction. Voir les docs.

Par exemple:

$("#anchor1").live("click", function() {
    $("#anchor1").append('<a class="myclass" href="#">test4</a>');
});

1
2017-08-31 19:31