动态内容上的事件处理程序无法工作

269

我有一个A标签,当点击它时,会添加另一个B标签来执行B动作。所以当我点击B标签时,B动作会被执行。然而,.on方法似乎无法在动态创建的B标签上起作用。

我的A标签的HTML和jQuery如下:

<a id="address" class="add_address btn btn-inverse btn-medium pull-right push-top">Add Shipping address</a>

$('.add_address').click(function(){
    //Add another <a>
    $(document).append('<a id="address"  class="pull-right update btn btn-inverse btn-medium push-top">Update</a>');
})

当标签B被点击时,会执行某些B动作。我的jQuery代码如下:
$('.update').on('click',function(){
  //action B
});

我有一些非动态内容,它们的类为“.update”。在上面的.on()方法中,对于非动态内容可以正常工作,但对于动态内容则不行。我该如何使其适用于动态内容?

1
你应该使用事件委托来绑定动态添加的DOM元素上的事件。http://api.jquery.com/delegate/ - Ashwin Parmar
2个回答

601

如果不添加选择器参数,则事件会直接绑定,而不是委托绑定。只有在元素已经存在时才能起作用(因此对于动态加载的内容无效)。

请参见http://api.jquery.com/on/#direct-and-delegated-events

将您的代码更改为

$(document.body).on('click', '.update' ,function(){

jQuery集接收事件,然后将其委托给与参数选择器匹配的元素。这意味着与使用live时相反,当执行代码时,jQuery集元素必须存在。

由于此答案受到了很多关注,因此以下是两个补充建议:

1) 在可能的情况下,尽量将事件监听器绑定到最精确的元素,以避免无用的事件处理。

也就是说,如果您要向现有的id为a的元素添加一个类b的元素,则不要使用

$(document.body).on('click', '#a .b', function(){

但使用

$('#a').on('click', '.b', function(){

2)注意,添加具有ID的元素时,请确保不要重复添加。在HTML中,拥有相同ID的两个元素不仅是“非法的”,还会破坏很多东西。例如,选择器"#c"将只检索具有此ID的一个元素。


4
或者在1.7之前使用delegate :) - Mathew Thompson
1
请注意,delegate和on的参数顺序相反:它是on('click','selector',function(){...}),但delegate('selector','click',function(){...})。 - PapaFreud
这在移动/平板设备上效果不佳。 - Anna
1
我在stackoverflow上看到了这篇帖子,它帮助我决定使用内联调用Javascript函数。https://dev59.com/Omkw5IYBdhLWcg3wEmWb - Anna
2
这个问题和答案都很棒。自昨天以来一直在绞尽脑汁!#smh..我想我又增加了编程技能。 - pkanane
显示剩余8条评论

30

.on函数中您缺少选择器:

.on(eventType, selector, function)

这个选择器非常重要!

http://api.jquery.com/on/

如果新的HTML被注入到页面中,需要在新的HTML放置到页面后选择元素并附加事件处理程序。或者,使用委托事件来附加事件处理程序。更多详情请参见jQuery 1.9 .live() is not a function

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接