使用jQuery将事件监听器添加到动态添加的元素

106

目前,我了解到为了将事件监听器附加到动态添加的元素上,您必须在添加元素后重新定义监听器。

有没有任何方法可以绕过这个问题,使您不必执行整个额外的代码块呢?


2
一个纯JS的解决方案:https://dev59.com/nHVC5IYBdhLWcg3wtzqs#27373951 - Ram Patra
4个回答

206

使用.on(),您可以定义一个函数一次,并且它将对任何动态添加的元素执行。

例如:

$('#staticDiv').on('click', 'yourSelector', function() {
  //do something
});

1
@Wiz 这是一个非常基本的jsfiddle,可以帮助你入门,你可能需要确保在元素上多次调用插件时不会发生任何不良反应。(请注意,我从其中一个演示开始了这个小工具,因为我没有看到hovercard插件的cdn) - Jack
我正在使用.one("mouseenter",但遇到了同样的障碍,有人可以帮忙吗?@Wiz - pavitran
如果“staticDiv”本身是动态的,你还能委托事件监听器吗? - HPWD
@HPWD 不行,但你可以一直向上访问DOM,如果需要的话可以直接委托给 body 元素(例如 $('body').on('click','.yourSelector', function () {...}))。 - Jack
1
@HPWD 两种方法都可以使用,文档位于DOM中body之上。实际效果不会有太大差别,但一般来说,您应该将事件处理程序绑定到尽可能接近的元素,以便它不会向上“冒泡”超过必要的范围。我建议您阅读有关事件冒泡的文章以获得更好的理解。 - Jack
显示剩余17条评论

49
$(document).on('click', 'selector', handler);

其中click是事件名称,而handler是事件处理程序,比如引用一个函数或匿名函数function() {}

PS:如果您知道要添加动态元素的特定节点,可以将其指定为document的替代项。


11
不要使用 $(document)。事件应该绑定到最近的静态父元素。 - Joseph Silber
7
@Joseph Silber:我已添加了 PS(附言)。而“不要使用”太绝对了。在某些情况下,使用它是合理的(甚至不用提它在 jQuery 文档中有规定:http://api.jquery.com/live/)。 - zerkms

6

您正在动态生成这些元素,因此在页面加载时应用的任何监听器都将不可用。我已经使用正确的解决方案编辑了您的fiddle。基本上,jQuery通过将事件附加到父元素并向下传播到正确的动态创建的元素来保留事件以供稍后绑定。

$('#musics').on('change', '#want',function(e) {
    $(this).closest('.from-group').val(($('#want').is(':checked')) ? "yes" : "no");
    var ans=$(this).val();
    console.log(($('#want').is(':checked')));
});

http://jsfiddle.net/swoogie/1rkhn7ek/39/


1
使用jQuery插件调用添加新元素时,可以按照以下方式进行:
$('<div>...</div>').hoverCard(function(){...}).appendTo(...)

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