jQuery jak powiązać Zdarzenie onclick z dynamicznie dodawanym elementem HTML

Chcę powiązać Zdarzenie onclick z elementem, który wstawiam dynamicznie za pomocą jQuery

Ale nigdy nie uruchamia funkcji binded. Byłbym szczęśliwy, gdybyś mógł wskazać, dlaczego ten przykład nie działa i jak Mogę sprawić, by działał poprawnie: {]}

<!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: edytowałem przykład, aby zawierał dwa elementy, do których metoda jest wstawiana. W takim przypadku wywołanie alert() nigdy nie zostanie wykonane. (dzięki @Daff za wskazanie tego w komentarzu)

Author: Saurabh Agrawal, 2009-10-06

9 answers

Pierwszy problem polega na tym, że gdy wywołujesz append na zestawie jQuery z więcej niż jednym elementem, tworzony jest klon elementu do dodania dla każdego z nich, a tym samym dołączony obserwator zdarzeń jest tracony.

Alternatywnym sposobem na to jest utworzenie dowiązania dla każdego elementu:

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

Innym potencjalnym problemem może być dołączenie obserwatora zdarzeń przed dodaniem elementu do DOM. Nie jestem pewien, czy to ma coś do powiedzenia, ale myślę, że zachowanie może być uznany za nieokreślony. Bardziej solidne podejście byłoby prawdopodobnie:

function handler() { alert('hello'); }
$('.add_to_this').each(function() {
  var link = $('<a>Click here</a>');
  $(this).append(link);
  link.click(handler);
});
 59
Author: Tobias,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-07 08:33:53

Wszystkie te metody są przestarzałe. Do rozwiązania problemu należy użyć metody on.

Jeśli chcesz kierować dynamicznie dodawany element, musisz użyć

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

To zastępuje przestarzałą metodę .live().

 268
Author: aM1Ne,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-10 12:47:16

A co z metodą na żywo?

$('.add_to_this a').live('click', function() {
    alert('hello from binded function call');
});
Ale to, co zrobiłeś, wygląda na to, że powinno zadziałać. Jest kolejny post , który wygląda dość podobnie.
 51
Author: Brother Erryn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:16

Trochę za późno na imprezę, ale pomyślałem, że spróbuję wyjaśnić pewne powszechne nieporozumienia w programach obsługi zdarzeń jQuery. W jQuery 1.7, .on() powinno być używane zamiast przestarzałego .live(), aby delegować procedury obsługi zdarzeń do elementów, które są dynamicznie tworzone w dowolnym momencie po przypisaniu procedury obsługi zdarzeń.

To powiedziawszy, nie jest proste przełączanie live na on, ponieważ składnia jest nieco inna:

Nowa metoda (przykład 1):

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

});

Deprecated metoda (przykład 2):

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

});

Jak pokazano powyżej, jest różnica. Przekręt jest .on() może być wywołany podobnie do .live(), przekazując selektor do samej funkcji jQuery:

Przykład 3:

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

});

Jednakże bez użycia $(document) jak w przykładzie 1, Przykład 3 nie będzie działał dla dynamicznie tworzonych elementów. Przykład 3 jest absolutnie w porządku, jeśli nie potrzebujesz dynamicznej delegacji.

Should $(document).on () być używane dla wszystko?

To zadziała, ale jeśli nie potrzebujesz dynamicznej delegacji, lepiej byłoby użyć przykładu 3, ponieważ przykład 1 wymaga nieco więcej pracy z przeglądarki. Nie będzie żadnego realnego wpływu na wydajność, ale warto użyć najbardziej odpowiedniej metody do użytku.

Powinien .on () być używane zamiast .kliknij (), Jeśli nie jest potrzebna dynamiczna delegacja?

Niekoniecznie. Poniżej znajduje się tylko skrót na przykład 3:
$('#something').click(function(){

});

Powyższe jest całkowicie poprawne i tak naprawdę jest to kwestia osobistych preferencji co do tego, która metoda jest używana, gdy nie jest wymagana dynamiczna delegacja.

Bibliografia:

 18
Author: MrCode,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-13 11:48:33

Rozważ to:

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...
        });
      });
});

Będzie działać, ponieważ dołączasz go do każdego konkretnego elementu. Dlatego po dodaniu linku do DOM musisz znaleźć sposób na jawne zaznaczenie dodanego elementu jako elementu jQuery w DOM i powiązanie z nim zdarzenia click.

Najlepszym sposobem prawdopodobnie będzie - zgodnie z sugestią-powiązanie go z konkretną klasą za pomocą metody live.

 1
Author: Daff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-06 14:30:39

Wierzę w dobry sposób:

$('#id').append('<a id="#subid" href="#">...</a>');
$('#subid').click( close_link );
 0
Author: yogsototh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-06 13:47:12

Jest możliwe i czasami konieczne utworzenie zdarzenia click wraz z elementem. Dzieje się tak na przykład wtedy, gdy Wiązanie oparte na selektorze nie jest opcją. Najważniejsze jest uniknięcie problemu, o którym mówił Tobias , używając .replaceWith() na jednym elemencie. Zauważ, że jest to tylko dowód koncepcji.

<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
Author: Nenotlep,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
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
Author: tanthuc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
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
Author: Sudeepta Majhee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-14 05:37:43