jQuery comment lier un événement onclick à un élément HTML ajouté dynamiquement

je veux lier un événement onclick à un élément que j'insère dynamiquement avec jQuery

mais il n'exécute jamais la fonction liée. Je serais heureux si vous pouvez rappeler pourquoi cet exemple ne fonctionne pas et comment je peux l'obtenir pour fonctionner correctement:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"        
            "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
        <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="da" lang="da">
        <head>
          <title>test of click binding</title>

<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
          <script type="text/javascript">


        jQuery(function(){
          close_link = $('<a class="" href="#">Click here to see an alert</a>');
          close_link.bind("click", function(){
            alert('hello from binded function call');
            //do stuff here...
          });
  
          $('.add_to_this').append(close_link);
        });
          </script>
        </head>
        <body>
          <h1 >Test of click binding</h1>
          <p>problem: to bind a click event to an element I append via JQuery.</p>

          <div class="add_to_this">
            <p>The link is created, then added here below:</p>
          </div>

          <div class="add_to_this">
            <p>Another is added here below:</p>
          </div>


        </body>
        </html>

EDIT: j'ai modifié l'exemple pour contenir deux éléments auxquels la méthode est insérée. dans ce cas, l'appel alert() n'est jamais exécuté. (merci à @Daff d'avoir souligné cela dans un commentaire)

119
demandé sur Saurabh Agrawal 2009-10-06 17:40:35

9 réponses

Le premier problème est que lorsque vous appelez ajouter sur un jQuery définir avec plus d'un élément, un clone de l'élément à ajouter est créé pour chacun et donc de l'événement attaché observateur est perdu.

, Une autre façon de le faire serait de créer un lien pour chaque élément:

function handler() { alert('hello'); }
$('.add_to_this').append(function() {
  return $('<a>Click here</a>').click(handler);
})

un autre problème potentiel pourrait être que l'observateur d'événement est attaché avant que l'élément ait été ajouté au DOM. Je ne sais pas si cela a quelque chose pour dire, mais je pense que le comportement pourrait être considéré comme indéterminé. Une approche plus solide serait probablement:

function handler() { alert('hello'); }
$('.add_to_this').each(function() {
  var link = $('<a>Click here</a>');
  $(this).append(link);
  link.click(handler);
});
59
répondu Tobias 2009-10-07 08:33:53

Toutes ces méthodes sont obsolètes. Vous devez utiliser la méthode on pour résoudre votre problème.

si vous voulez cibler un élément ajouté dynamiquement, vous devrez utiliser

$(document).on('click', selector-to-your-element , function() {
     //code here ....
});

remplacer la méthode dépréciée .live() .

268
répondu aM1Ne 2013-10-10 12:47:16

et la méthode Live?

$('.add_to_this a').live('click', function() {
    alert('hello from binded function call');
});

toujours, ce que vous avez fait à propos de l'apparence comme il devrait fonctionner. Il y a un autre post qui ressemble assez similaire.

51
répondu Brother Erryn 2017-05-23 10:31:16

un peu tard pour la fête, mais j'ai pensé que je pourrais essayer de clarifier certaines idées fausses communes dans jQuery event handlers. À partir de jQuery 1.7, .on() devrait être utilisé à la place du .live() déprécié , pour déléguer les gestionnaires d'événements aux éléments qui sont créés dynamiquement à tout moment après que le gestionnaire d'événements est assigné.

cela dit, il n'est pas simple de changer live pour on parce que la syntaxe est légèrement différente:

nouvelle méthode (exemple 1):

$(document).on('click', '#someting', function(){

});

méthode dépréciée (exemple 2):

$('#something').live(function(){

});

Comme indiqué ci-dessus, il y a une différence. La torsion est .on() peut en fait être appelé similaire à .live() , en passant le sélecteur à la fonction jQuery elle-même:

exemple 3:

$('#something').on('click', function(){

});

cependant, sans utiliser $(document) comme dans l'exemple 1, l'exemple 3 NE FONCTIONNERA PAS pour éléments créés dynamiquement. L'exemple 3 est absolument parfait si vous n'avez pas besoin de la délégation dynamique.

Doit $(document).() peut être utilisé pour tout?

cela fonctionnera, mais si vous n'avez pas besoin de la délégation dynamique, il serait plus approprié d'utiliser l'exemple 3 parce que l'exemple 1 nécessite un peu plus de travail à partir du navigateur. Il n'y aura pas d'impact réel sur la performance mais il est logique d'utiliser le plus méthode appropriée pour votre utilisation.

devrait .() peut être utilisé au lieu de .cliquez sur () si aucune délégation dynamique n'est nécessaire?

pas nécessairement. Ce qui suit n'est qu'un raccourci pour l'exemple 3:

$('#something').click(function(){

});

ce qui précède est parfaitement valable et c'est donc une question de préférence personnelle quant à la méthode utilisée lorsqu'aucune délégation dynamique n'est requise.

références:

18
répondu MrCode 2013-06-13 11:48:33

considérez ceci:

jQuery(function(){
  var close_link = $('<a class="" href="#">Click here to see an alert</a>');
      $('.add_to_this').append(close_link);
      $('.add_to_this').children().each(function()
      {
        $(this).click(function() {
            alert('hello from binded function call');
            //do stuff here...
        });
      });
});

cela fonctionnera parce que vous l'attachez à chaque élément spécifique. C'est pourquoi vous avez besoin - après avoir ajouté votre lien vers le DOM - de trouver un moyen de sélectionner explicitement votre élément ajouté en tant qu'élément JQuery dans le DOM et d'y lier l'événement de clic.

la meilleure façon sera probablement - comme suggéré - de le lier à une classe spécifique via la méthode live.

1
répondu Daff 2009-10-06 14:30:39

je crois que la bonne façon de le faire:

$('#id').append('<a id="#subid" href="#">...</a>');
$('#subid').click( close_link );
0
répondu yogsototh 2009-10-06 13:47:12

Il est possible et parfois nécessaire pour créer l'événement click avec l'élément. C'est par exemple le cas lorsque la liaison par sélecteur n'est pas une option. L'essentiel est d'éviter le problème dont parlait Tobias en utilisant .replaceWith() sur un seul élément. Notez qu'il ne s'agit que d'une validation de principe.

<script>
    // This simulates the object to handle
    var staticObj = [
        { ID: '1', Name: 'Foo' },
        { ID: '2', Name: 'Foo' },
        { ID: '3', Name: 'Foo' }
    ];
    staticObj[1].children = [
        { ID: 'a', Name: 'Bar' },
        { ID: 'b', Name: 'Bar' },
        { ID: 'c', Name: 'Bar' }
    ];
    staticObj[1].children[1].children = [
        { ID: 'x', Name: 'Baz' },
        { ID: 'y', Name: 'Baz' }
    ];

    // This is the object-to-html-element function handler with recursion
    var handleItem = function( item ) {
        var ul, li = $("<li>" + item.ID + " " + item.Name + "</li>");

        if(typeof item.children !== 'undefined') {
            ul = $("<ul />");
            for (var i = 0; i < item.children.length; i++) {
                ul.append(handleItem(item.children[i]));
            }
            li.append(ul);
        }

        // This click handler actually does work
        li.click(function(e) {
            alert(item.Name);
            e.stopPropagation();
        });
        return li;
    };

    // Wait for the dom instead of an ajax call or whatever
    $(function() {
        var ul = $("<ul />");

        for (var i = 0; i < staticObj.length; i++) {
            ul.append(handleItem(staticObj[i]));
        }

        // Here; this works.
        $('#something').replaceWith(ul);
    });
</script>
<div id="something">Magical ponies ♥</div>
0
répondu Nenotlep 2017-05-23 12:34:42
    function load_tpl(selected=""){
        $("#load_tpl").empty();
        for(x in ds_tpl){
            $("#load_tpl").append('<li><a id="'+ds_tpl[x]+'" href="#" >'+ds_tpl[x]+'</a></li>');
        }
        $.each($("#load_tpl a"),function(){
            $(this).on("click",function(e){
                alert(e.target.id);
            });
        });
    }
0
répondu tanthuc 2017-06-06 00:19:40
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>    
<script>
    $(document).ready(function(){
        $(document).on('click', '.close', function(){
            var rowid='row'+this.id;
            var sl = '#tblData tr[id='+rowid+']';
            console.log(sl);
            $(sl).remove();
        });
        $("#addrow").click(function(){
            var row='';
            for(var i=0;i<10;i++){
                row=i;
                row='<tr id=row'+i+'>'
                    +   '<td>'+i+'</td>'
                    +   '<td>ID'+i+'</td>'
                    +   '<td>NAME'+i+'</td>'
                    +   '<td><input class=close type=button id='+i+' value=X></td>'
                    +'</tr>';
                console.log(row);
                $('#tblData tr:last').after(row);
            }
        });
    });

</script>
</head>
  <body>
    <br/><input type="button" id="addrow" value="Create Table"/>
    <table id="tblData" border="1" width="40%">
        <thead>
        <tr>
            <th>Sr</th>
            <th>ID</th>
            <th>Name</th>
            <th>Delete</th>
        </tr>
        </thead>
    </table>
    </body>
 </html>
-2
répondu Sudeepta Majhee 2017-05-14 05:37:43