关于javascript:jQuery如何将onclick事件绑定到动态添加的HTML元素

jQuery how to bind onclick event to dynamically added HTML element

本问题已经有最佳答案,请猛点这里访问。

我想将onclick事件绑定到用jquery动态插入的元素

但它从不运行绑定函数。如果您能指出这个示例为什么不起作用,以及如何使它正常运行,我将非常高兴:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<!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>
          test of click binding

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


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

         
            <p>
The link is created, then added here below:
</p>
         

         
            <p>
Another is added here below:
</p>
         


        </body>
        </html>

编辑:我编辑了这个示例以包含插入方法的两个元素。在这种情况下,不会执行alert()调用。(感谢@daff在评论中指出这一点)


所有这些方法都已弃用。您应该使用on方法来解决您的问题。

如果要以动态添加的元素为目标,则必须使用

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

这将替换已弃用的.live()方法。


第一个问题是,当使用多个元素对jquery集调用append时,将为每个元素创建要附加的元素的克隆,从而丢失附加的事件观察者。

另一种方法是为每个元素创建链接:

1
2
3
4
function handler() { alert('hello'); }
$('.add_to_this').append(function() {
  return $('Click here').click(handler);
})

另一个潜在的问题可能是,事件观察者在元素被添加到DOM之前被附加。我不确定这是否有什么要说的,但我认为这种行为可能被认为是不确定的。更可靠的方法可能是:

1
2
3
4
5
6
function handler() { alert('hello'); }
$('.add_to_this').each(function() {
  var link = $('Click here');
  $(this).append(link);
  link.click(handler);
});


实况转播怎么样?

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

不过,你所做的看起来应该是可行的。还有一个帖子看起来很相似。


派对稍微晚了一点,但我想我会尝试清除jquery事件处理程序中的一些常见误解。从jquery 1.7开始,应该使用.on()而不是不推荐使用的.live(),将事件处理程序委托给在分配事件处理程序后的任意点动态创建的元素。

也就是说,切换onlive并不是简单的,因为语法略有不同:

新方法(示例1):

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

});

不推荐使用的方法(示例2):

1
2
3
$('#something').live(function(){

});

如上图所示,两者之间存在差异。通过将选择器传递给jquery函数本身,实际上可以调用与.live()类似的twist:.on()

例3:

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

});

但是,如果不象例1那样使用$(document),例3将不适用于动态创建的元素。如果您不需要动态委托,那么示例3就完全可以了。

Should $(document).on() be used for everything?

它可以工作,但是如果您不需要动态委托,那么使用示例3更合适,因为示例1需要从浏览器进行稍微多的工作。不会对性能产生任何实际影响,但使用最合适的方法是有意义的。

Should .on() be used instead of .click() if no dynamic delegation is needed?

不一定。以下只是一个快捷方式,例如3:

1
2
3
$('#something').click(function(){

});

上述方法是完全有效的,因此,在不需要动态委托的情况下,使用哪种方法确实是个人偏好的问题。

参考文献:

  • j.on()查询单
  • j.click()查询单
  • j.live()查询单

考虑一下:

1
2
3
4
5
6
7
8
9
10
11
jQuery(function(){
  var close_link = $('Click here to see an alert');
      $('.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之后,您需要找到一种方法来显式地选择添加的元素作为DOM中的jquery元素,并将click事件绑定到它。

正如建议的那样,最好的方法可能是通过live方法将它绑定到特定的类。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    function load_tpl(selected=""){
        $("#load_tpl").empty();
        for(x in ds_tpl){
            $("#load_tpl").append('
<li>
'
+ds_tpl[x]+'
</li>
'
);
        }
        $.each($("#load_tpl a"),function(){
            $(this).on("click",function(e){
                alert(e.target.id);
            });
        });
    }


有时可能需要与元素一起创建click事件。例如,当基于选择器的绑定不是选项时。关键部分是通过在单个元素上使用.replaceWith(),避免Tobias所讨论的问题。请注意,这只是一个概念证明。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
    // 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);
    });

Magical ponies ?

我相信这样做的好方法:

1
2
$('#id').append('...');
$('#subid').click( close_link );


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js">    

    $(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);
            }
        });
    });


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