jQuery.on() 是不是适用于在创建事件处理程序后添加的元素?

Posted

技术标签:

【中文标题】jQuery.on() 是不是适用于在创建事件处理程序后添加的元素?【英文标题】:Does jQuery.on() work for elements that are added after the event handler is created?jQuery.on() 是否适用于在创建事件处理程序后添加的元素? 【发布时间】:2012-04-06 13:02:08 【问题描述】:

一直以来我的印象是.on() 在动态创建的元素方面与.live() 一样工作(例如,我使用$('.foo').on('click', function()alert('click'));,然后由于某些AJAX 而创建了一个类foo 的元素,现在我希望单击该元素会引起警报)。在实践中,这些不是我得到的结果。我可能会犯错误,但有人可以帮助我了解在.on() 之后实现这些结果的方法吗?

提前致谢。

【问题讨论】:

【参考方案1】:

.on() 如果使用得当,可以与动态创建的元素一起使用。 jQuery doc 很好地描述了它。

动态元素的使用方式是使用这种形式:

$("static selector").on('click', "dynamic selector", fn);

静态选择器必须解析为既是动态对象的祖先又是静态的对象 - 在您运行这行代码时存在并且不会被删除或重新创建。

动态选择器是与您的动态元素匹配的选择器。它们不必在首次安装事件处理程序时就存在,它们可以随心所欲地来来去去。

所以,如果"#container" 匹配静态祖先并且".foo" 匹配您希望点击处理程序的动态元素,您将使用它;

$("#container").on("click", ".foo", fn);

如果你真的想了解它,这就是.on() 的委托事件处理的工作原理。当您在上面进行.on() 调用时,它会将单击事件处理程序附加到#container 对象。稍后,当您单击 .foo 对象时,实际的 .foo 对象上没有单击处理程序,因此单击会在祖先链上冒泡。当点击到达#container 对象时,会有一个点击处理程序,jQuery 会查看该处理程序并发现该处理程序仅适用于原始点击对象与选择器".foo" 匹配的对象。它测试事件目标以查看它是否匹配该选择器,如果匹配,则调用它的事件处理程序。

(现已弃用).live() 方法通过将所有事件处理程序附加到文档对象来工作。由于文档对象是文档中每个对象的祖先,因此它们以这种方式获得了委托事件处理。所以,在上面的例子中,这两个是等价的:

$(document).on("click", ".foo", fn);
$(".foo").live("click", fn);

但是,在文档上附加所有委托的事件处理程序有时会造成严重的性能瓶颈,因此 jQuery 认为这是一种不好的方法,最好要求开发人员指定一个希望更接近实际的静态祖先目标对象比文档对象。

【讨论】:

很好的答案,但我不同意“jQuery doc 在描述它方面做得很好。”。如果它做得很好,那么在 SO 和搜索它的人(比如我)就不会有那么多问题了。【参考方案2】:

我认为您面临与我类似的情况。这对于将事件与稍后生成的元素绑定是一个很好的解决方案。

Binding Jquery Events On Elements Generated Through Other Events

【讨论】:

以上是关于jQuery.on() 是不是适用于在创建事件处理程序后添加的元素?的主要内容,如果未能解决你的问题,请参考以下文章

JQuery .on() 没有将点击事件绑定到动态创建的元素[重复]

jQuery on注册事件

具有多个事件处理程序的 JQuery .on() 方法到一个选择器

直接与委托 - jQuery .on()

jquery $.on() 和使用 date() 时处理奇怪行为的触摸事件

将函数传递给 jquery On 事件处理程序