web-dev-qa-db-fra.com

L'événement de clic ne fonctionne pas sur les éléments générés dynamiquement

<html>
<head>
    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript">

        $(document).ready(function() {

            $("button").click(function() {
                $("h2").html("<p class='test'>click me</p>")
            });   

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

    </script>
</head>
<body>
    <h2></h2>
    <button>generate new element</button>
</body>
</html>

J'essayais de générer une nouvelle balise avec le nom de classe test dans le <h2> en cliquant sur le bouton. J'ai également défini un événement de clic associé à test. Mais l'événement ne fonctionne pas.

Quelqu'un peut-il aider?

453
cheng

La liaison click() que vous utilisez est appelée une liaison "directe" qui attachera uniquement le gestionnaire aux éléments qui existent déjà . Il ne sera pas lié aux éléments créés dans le futur. Pour ce faire, vous devrez créer une liaison "déléguée" en utilisant on() .

Les événements délégués ont l'avantage de pouvoir traiter des événements issus d'éléments descendants ajoutés au document ultérieurement.

Source

Voici ce que vous recherchez:

var counter = 0;

$("button").click(function() {
    $("h2").append("<p class='test'>click me " + (++counter) + "</p>")
});

// With on():

$("h2").on("click", "p.test", function(){
    alert($(this).text());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<h2></h2>
<button>generate new element</button>

Ce qui précède fonctionne pour les utilisateurs de jQuery version 1.7+. Si vous utilisez une version plus ancienne, reportez-vous à la réponse précédente ci-dessous.


Réponse précédente :

Essayez d’utiliser live() :

$("button").click(function(){
    $("h2").html("<p class='test'>click me</p>")
});   


$(".test").live('click', function(){
    alert('you clicked me!');
});

Travaillé pour moi essayé avec jsFiddle.

Ou il y a une nouvelle façon de le faire avec delegate() :

$("h2").delegate("p", "click", function(){
    alert('you clicked me again!');
});

n jsFiddle mis à jour .

652
Cᴏʀʏ

Utilisez la méthode .on() avec des événements délégués

$('#staticParent').on('click', '.dynamicElement', function() {
    // Do something on an existent or future .dynamicElement
});

La méthode .on() vous permet de déléguer tout gestionnaire d'événement souhaité à:
éléments actuels ou éléments futurs ajoutés au DOM à un moment ultérieur.

P.S: N'utilisez pas .live()! Depuis jQuery 1.7+, la méthode .live() est obsolète.

205
Roko C. Buljan

Raison:

Dans jQuery, Click () - attache le gestionnaire d'événements uniquement si l'élément existe déjà dans le code html.

Il ne tiendra pas compte du nouvel élément créé dynamiquement (élément Future) après le chargement de la page.

Les éléments dynamiques sont créés à l'aide de javascript ou jquery (pas en html).

Donc, l'événement click ne se déclenche pas.

Solution:

Pour surmonter cela, nous devrions utiliser la fonction on ().

Les fonctions delegate (), live () et on () ont les avantages sur les éléments DOM.

on peut déclencher à la fois des éléments existants et des éléments futurs.

on peut considérer les éléments qui sont tous présents dans la page entière.

les fonctions delegate () et live () sont obsolètes (ne les utilisez pas).

Vous devez utiliser la fonction on pour déclencher l'événement sur les éléments (futurs) créés dynamiquement.

Supprimez le code de $ (document) .ready:

$(".test").click(function(){

  alert();

});

Changer en:

$(document).on('click','.test',function(){

  alert('Clicked');

});
93
Prabhagaran

Ajoutez cette fonction dans votre fichier js.Cela fonctionnera sur tous les navigateurs

$(function() {
    $(document).on("click", '#mydiv', function() {
        alert("You have just clicked on ");
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='mydiv'>Div</div>
19
Abhishek

Changement

 $(".test").click(function(){

À

 $(".test").live('click', function(){

LIVE DEMO

jQuery .live()

13
qwertymk

Vous devez utiliser . Live pour que cela fonctionne:

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

ou si vous utilisez jquery 1.7+ utilisez . on :

$(".test").on("click", "p", function(){
   alert();
});
12
amurra

Essayez .live() ou .delegate()

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

http://api.jquery.com/delegate/

Votre élément .test a été ajouté après la méthode .click(), de sorte que l'événement ne lui était pas associé. Live et Delegate donnent le déclencheur de cet événement aux éléments parents qui vérifient leurs enfants. Ainsi, tout élément ajouté par la suite fonctionne toujours. Je pense que Live vérifiera le corps du document dans son intégralité, alors que Délégué peut être attribué à un élément, donc Déléguer est plus efficace.

Plus d'informations:

http://www.alfajango.com/blog/the-difference-between-jquerys-bind-live-and-delegate/

7
DSKrepps

J'ai trouvé deux solutions dans la documentation de jQuery:

Premièrement: utiliser un délégué sur un corps ou un document

Par exemple:

 $("body").delegate('.test', 'click', function(){
 ...
  alert('test');
 });

Pourquoi?

Réponse: Attache un gestionnaire à un ou plusieurs événements pour tous les éléments qui correspondent au sélecteur, maintenant ou à l'avenir, en fonction d'un ensemble spécifique d'éléments racines . lien: http://api.jquery.com/delegate/

Deuxièmement: Placez la fonction your au "$ (document)" , en utilisant "sur" et attachez-la à l'élément qui vous voulez déclencher cela. Le premier paramètre est le "gestionnaire d'événements", le second: l'élément et le troisième: la fonction. Par exemple:

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

Pourquoi?

Réponse: Les gestionnaires d'événements ne sont liés qu'aux éléments actuellement sélectionnés. ils doivent exister sur la page au moment où votre code appelle . on () . Pour vous assurer que les éléments sont présents et peuvent être sélectionnés, effectuez la liaison d'événement dans un gestionnaire de document prêt pour les éléments figurant dans le balisage HTML de la page. Si un nouveau code HTML est injecté dans la page, sélectionnez les éléments et associez des gestionnaires d’événements une fois le nouveau code HTML inséré dans la page. Ou bien, utilisez des événements délégués pour attacher un gestionnaire d’événements, comme décrit dans le lien suivant ... lien: https://api.jquery.com/on/

6
user3425150

Meilleure façon d'appliquer l'événement sur un contenu généré dynamiquement à l'aide de la délégation.

$(document).on("eventname","selector",function(){
    // code goes here
});

alors votre code est comme ça maintenant

$(document).on("click",".test",function(){
    // code goes here
});
5
Jay Patel

Le problème que vous avez est que vous essayez de lier la classe "test" à l'événement avant qu'il y ait quoi que ce soit avec une classe "test" dans le DOM. Bien que vous ayez l’impression que tout cela soit dynamique, ce qui se passe réellement est que JQuery passe au-dessus de DOM et connecte l’événement de clic lorsque la fonction ready() est activée, ce qui se produit avant vous. créé le "Cliquez-moi" dans votre événement de bouton.

En ajoutant l'événement de test "test" au gestionnaire de clics "bouton", il sera connecté après que le bon élément existe dans la variable DOM.

<script type="text/javascript">
    $(document).ready(function(){                          
        $("button").click(function(){                                  
            $("h2").html("<p class='test'>click me</p>")                          
            $(".test").click(function(){                          
                alert()                          
            });       
        });                                     
    });
</script>

Utiliser live() (comme d'autres l'ont souligné) est une autre façon de procéder, mais j'estimais que c'était également une bonne idée de signaler l'erreur mineure dans votre code JS. Ce que vous avez écrit n’était pas faux, il fallait simplement que celui-ci soit correctement défini. Comprendre le fonctionnement de DOM et de JS est l’un des problèmes que beaucoup de développeurs traditionnels doivent comprendre.

live() est une manière plus simple de gérer cela et, dans la plupart des cas, la bonne façon de procéder. Il s’agit essentiellement de surveiller la DOM et de réorganiser les choses chaque fois que les éléments qui le composent changent.

4
Marc LaFleur
$(.surrounding_div_class).on( 'click', '.test', function () {
alert( 'WORKS!' );
});

Ne fonctionnera que si la DIV avec la classe .surrounding_div_class est le parent immédiat de l'objet .test

S'il y a un autre objet dans la div qui sera rempli, cela ne fonctionnera pas.

4
Nikolaus Pluta

La fonction live fonctionne très bien.

C'est pour les éléments ajoutés dynamiquement à la scène.

$('#selectAllAssetTypes').live('click', function(event){
                    alert("BUTTON CLICKED");
                    $('.assetTypeCheckBox').attr('checked', true);
                });

Cheers, Ankit.

3
Ankit Tanna

Si vous avez un lien dinamically ajouté à un conteneur ou au corps:

var newLink= $("<a></a>", {
        "id": "approve-ctrl",
        "href": "#approve",
        "class": "status-ctrl",
        "data-attributes": "DATA"
    }).html("Its ok").appendTo(document.body);

vous pouvez prendre son élément javascript brut et y ajouter un écouteur d'événement, comme le clic :

newLink.get(0).addEventListener("click", doActionFunction);

Peu importe le nombre de fois que vous ajoutez cette nouvelle instance de lien, vous pouvez l'utiliser comme si vous utilisiez une fonction jquery click.

function doActionFunction(e) {
    e.preventDefault();
    e.stopPropagation();

    alert($(this).html());
}

Donc, vous recevrez un message disant

C'est bon

Il a de meilleures performances que d'autres alternatives.

Extra: Vous pourriez obtenir de meilleures performances en évitant jquery et l’utilisation de javascript. Si vous utilisez IE jusqu'à la version 8, vous devez utiliser ce polyfill pour utiliser la méthode addEventListener

if (typeof Element.prototype.addEventListener === 'undefined') {
    Element.prototype.addEventListener = function (e, callback) {
      e = 'on' + e;
      return this.attachEvent(e, callback);
    };
  }
3
EliuX

Une alternative alternative plus succincte (IMHO) consiste à utiliser une fonction javascript brute qui répond à un événement au clic, puis à renvoyer l'élément cible à jQuery si vous le souhaitez. L'avantage de cette approche est que vous pouvez ajouter dynamiquement votre élément n'importe où, et que le gestionnaire de clics "fonctionne" et que vous n'avez pas à vous préoccuper de la délégation du contrôle aux éléments parents, etc.

Étape 1: Mettez à jour le code HTML dynamique pour déclencher un événement onclick. Assurez-vous de passer l'objet 'event' comme argument

 
 $ ("bouton"). cliquez sur (fonction () {
 $ ("h2"). html ("<p class = 'test'  onclick = 'test (événement)' > cliquez sur moi </ p> ") 
}); 
 

Étape 2: Créez la fonction de test pour répondre à l'événement de clic.

 
 test de fonctionnement (e) {
 alert (); 
}); 
 

Étape facultative 3: Étant donné que vous utilisez jQuery, je suppose qu'il sera utile de renvoyer une référence au bouton source.

 
 test de fonctionnement (e) {
 alert (); 
 
 // Obtenir une référence au bouton 
 // Une explication de cette ligne est disponible  ici  
 Var target = (e.target)? e.target: e.srcElement; 
 
 // Passez la référence du bouton à jQuery pour faire de la magie jQuery 
 var $ btn = $ (cible); 
 
}); 
 
3
Nick Mitchell

Je ne pouvais pas vivre ou déléguer pour travailler sur une div dans une lightbox (tinybox).

J'ai utilisé setTimeout avec succès, de la manière simple suivante:

$('#displayContact').click(function() {
    TINY.box.show({html:'<form><textarea id="contactText"></textarea><div id="contactSubmit">Submit</div></form>', close:true});
    setTimeout(setContactClick, 1000);
})

function setContactClick() {
    $('#contactSubmit').click(function() {
        alert($('#contactText').val());
    })
}
3
Sasha Shepherd

Vous pouvez aussi utiliser l'élément onclick="do_something(this)"inside

3
Daryn K.

Jquery .on fonctionne bien, mais le rendu lors de l’application de certaines des solutions ci-dessus a posé quelques problèmes. Mon problème avec le .on est qu’il rendait les événements différemment de la méthode .hover.

Juste fyi pour quelqu'un d'autre qui peut aussi avoir le problème. J'ai résolu mon problème en ré-enregistrant l'événement de survol pour l'élément ajouté dynamiquement:

ré-enregistrer l'événement de survol, car le survol ne fonctionne pas pour les éléments créés dynamiquement. donc chaque fois que je crée le nouvel élément/dynamique, j'ajoute à nouveau le code de survol. fonctionne parfaitement

$('#someID div:last').hover(
    function() {
       //...
    },
    function() {
       //...
    }
);
3
user2257720

Vous POUVEZ ajouter des clics sur des éléments créés dynamiquement. Exemple ci-dessous. Utiliser un moment pour s’assurer que c’est fait. Dans mon exemple, je saisis une div avec la classe expand, en ajoutant une étendue "cliquez pour en voir plus", puis en utilisant cette étendue pour afficher/masquer la div d'origine.

$.when($(".expand").before("<span class='clickActivate'>Click to see more</span>")).then(function(){
    $(".clickActivate").click(function(){
        $(this).next().toggle();
    })
});
2
Daryl H

Je travaille avec des tables en ajoutant de nouveaux éléments de manière dynamique, et lors de l'utilisation de on (), le seul moyen de le faire fonctionner pour moi est d'utiliser un parent non dynamique comme:

<table id="myTable">
    <tr>
        <td></td> // Dynamically created
        <td></td> // Dynamically created
        <td></td> // Dynamically created
    </tr>
</table>

<input id="myButton" type="button" value="Push me!">

<script>
    $('#myButton').click(function() {
        $('#myTable tr').append('<td></td>');
    });

    $('#myTable').on('click', 'td', function() {
        // Your amazing code here!
    });
</script>

Ceci est vraiment utile car, pour supprimer les événements liés à on () , vous pouvez utiliser off () , et pour utiliser les événements une fois, vous pouvez utiliser n () .

2
Timbergus

Utilisez 'on' car le clic est lié aux éléments déjà présents.

Par exemple

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

CA aidera.

0
Abhijit