Как связать событие onclick с динамически добавленным элементом HTML

javascript jquery bind

237802 просмотра

9 ответа

Я хочу привязать событие onclick к элементу, который я вставляю динамически с помощью jQuery

Но он никогда не запускает связанную функцию. Я был бы счастлив, если бы вы могли указать, почему этот пример не работает и как я могу заставить его работать правильно:

<!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>

РЕДАКТИРОВАТЬ: я отредактировал пример, чтобы содержать два элемента, в которые вставлен метод. В этом случае alert()вызов никогда не выполняется. (спасибо @Daff за то, что указал на это в комментарии)

Автор: Jesper Rønn-Jensen Источник Размещён: 12.11.2019 09:08

Ответы (9)


60 плюса

Решение

Первая проблема заключается в том, что когда вы вызываете append для набора jQuery с более чем одним элементом, для каждого из них создается клон добавляемого элемента, и, таким образом, прикрепленный наблюдатель событий теряется.

Альтернативный способ сделать это - создать ссылку для каждого элемента:

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

Другая потенциальная проблема может заключаться в том, что наблюдатель события присоединяется до того, как элемент добавлен в DOM. Я не уверен, есть ли что сказать, но я думаю, что поведение можно считать неопределенным. Более надежный подход, вероятно, будет:

function handler() { alert('hello'); }
$('.add_to_this').each(function() {
  var link = $('<a>Click here</a>');
  $(this).append(link);
  link.click(handler);
});
Автор: Tobias Размещён: 07.10.2009 08:33

282 плюса

Все эти методы устарели. Вы должны использовать onметод, чтобы решить вашу проблему.

Если вы хотите настроить таргетинг на динамически добавленный элемент, вам придется использовать

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

это заменить устаревший .live()метод.

Автор: aM1Ne Размещён: 01.10.2012 01:03

51 плюса

Как насчет метода Live?

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

Тем не менее, то, что вы сделали, похоже, должно работать. Есть еще один пост, который выглядит довольно похоже.

Автор: Brother Erryn Размещён: 06.10.2009 01:53

18 плюса

Немного опоздал на вечеринку, но подумал, что попытаюсь выяснить некоторые распространенные заблуждения в обработчиках событий jQuery. Начиная с jQuery 1.7, .on()следует использовать вместо устаревших .live(), чтобы делегировать обработчики событий элементам, которые динамически создаются в любой точке после назначения обработчика событий.

Тем не менее, это не просто переключение liveна onпотому что синтаксис немного отличается:

Новый метод (пример 1):

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

});

Устаревший способ (пример 2):

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

});

Как показано выше, есть разница. Поворот .on()можно на самом деле вызвать аналогично .live(), передав селектор самой функции jQuery:

Пример 3:

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

});

Однако без использования, $(document)как в примере 1, пример 3 не будет работать для динамически создаваемых элементов. Пример 3 вполне подходит, если вам не нужно динамическое делегирование.

Следует ли использовать $ (document) .on () для всего?

Это будет работать, но если вам не нужно динамическое делегирование, было бы более целесообразно использовать пример 3, потому что пример 1 требует немного больше работы из браузера. Реального влияния на производительность не будет, но имеет смысл использовать наиболее подходящий для вас метод.

Следует ли использовать .on () вместо .click (), если динамическое делегирование не требуется?

Не обязательно. Следующее является просто ярлыком для примера 3:

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

});

Вышеприведенное совершенно верно, и поэтому на самом деле все зависит от личных предпочтений относительно того, какой метод используется, когда динамическое делегирование не требуется.

Рекомендации:

Автор: MrCode Размещён: 13.06.2013 11:48

1 плюс

Учти это:

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

Это будет работать, потому что вы прикрепляете его к каждому конкретному элементу. Вот почему вам нужно - после добавления вашей ссылки в DOM - найти способ явно выбрать добавленный элемент в качестве элемента JQuery в DOM и привязать к нему событие click.

Вероятно, наилучшим способом будет, как и предполагалось, связать его с конкретным классом с помощью метода live.

Автор: Daff Размещён: 06.10.2009 01:43

0 плюса

Я считаю, хороший способ это сделать:

$('#id').append('<a id="#subid" href="#">...</a>');
$('#subid').click( close_link );
Автор: yogsototh Размещён: 06.10.2009 01:47

0 плюса

Возможно и иногда необходимо создать событие click вместе с элементом. Это, например, когда привязка на основе селектора не является опцией. Ключевая часть состоит в том, чтобы избежать проблемы, о которой говорил Тобиас , используя .replaceWith()один элемент. Обратите внимание, что это просто доказательство концепции.

<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>
Автор: Nenotlep Размещён: 09.07.2013 08:13

0 плюса

    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);
            });
        });
    }
Автор: tanthuc Размещён: 06.06.2017 12:19

-2 плюса

<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>
Автор: Sudeepta Majhee Размещён: 14.05.2017 04:43
Вопросы из категории :
32x32