动态元素的jQuery加载事件

38

我正在尝试对动态添加到页面某个容器中的元素进行一些条件性操作,但我缺少一个事件。

假设我有一个容器:

<div id="container"></div>

我可以轻松地使用以下代码将事件处理程序绑定到所有新元素的单击函数中:

$('#container').on('click', '.sub-element', function() { ... });
但是,我该绑定什么才能在元素添加到#container时获取一个“一次性”钩子?我已经尝试了绑定readyload,但都没有成功。有没有其他方法可以实现这个功能,或者我必须想出另一种解决方案来解决我的问题? 这个演示包含了我不起作用的例子。

2
在所有浏览器中,加载事件不会冒泡。在 Internet Explorer 8 及更低版本中,粘贴和重置事件不会冒泡。这些事件不支持使用委托,但可以在事件处理程序直接附加到生成事件的元素时使用。现在,关于如何解决这个问题... - Corbin
你尝试实现的“加载”功能是否可以完全删除,改为在项目添加后通过“链接”操作html? $('#container').append('<div class="sub-element">No worky!</div>').html('<b>yaay!</b>'); - Ohgodwhy
@Ohgodwhy,我并不是不能想出解决方法(尤其是对于这个愚蠢的例子),我只是想知道是否有我错过的事件可以用于我所描述的目的。 - Klaus Byskov Pedersen
@Corbin,“load”事件仅在与URL相关联的元素上触发,例如图像或样式表。 - Jasper
我其实在我的评论中开始写这个,但是考虑到你无论如何都不能在加载时委派,这没关系。不过包括进去也好。 - Corbin
2个回答

43

您可以在新添加的DOM元素上触发一个自定义事件,然后可以通过jQuery事件处理程序进行捕获:

//bind to our custom event for the `.sub-element` elements
$('#container').on('custom-update', '.sub-element', function(){
    $(this).html('<b>yaay!</b>');
});

//append a new element to the container,
//then select it, based on the knowledge that it is the last child of the container element,
//and then trigger our custom event on the element
$('#container').append('<div class="sub-element">No worky!</div>').children().last().trigger('custom-update');

以下是一个示例:http://jsfiddle.net/ggHh7/4/

即使您通过不同的方法加载动态内容,此方法允许您在全局范围内执行某些操作。

更新

我不确定浏览器的支持情况(我假设IE8及更早版本不支持此功能),但您可以使用DOMNodeInserted突变事件来检测何时添加了DOM元素:

$('#container').on('DOMNodeInserted', '.sub-element', function(){
    $(this).html('<b>yaay!</b>');
})

$('#container').append('<div class="sub-element">No worky!</div>');

这里有一个演示:http://jsfiddle.net/ggHh7/7/

更新

现在有一个新的 API,因为DOMNodeInserted已经过时了。我没有深入研究过它,但它被称为MutationObserverhttps://developer.mozilla.org/en-US/docs/Web/API/MutationObserver


有趣,+1,還有...你的意思是說,沒有辦法讓我在第三方插件將元素添加到某個容器時得到通知嗎?如果不是我添加它,那我就完了? - Klaus Byskov Pedersen
3
你可以设置一个时间间隔,每隔一段时间检查新的DOM元素。否则,还有变异事件, DOMNodeInserted 可能是你想要的,但浏览器支持可能不够: https://developer.mozilla.org/en/DOM_Client_Object_Cross-Reference/DOM_Events (请查看“Mutation and mutation name event types”部分)。参见我的 update 中使用 DOMNodeInserted 的示例。 - Jasper
你需要使用一种像长轮询这样的方法来监视元素长度的变化,如果长度发生变化,则获取长度差异。这将给你任何驻留在那里的“对象”。虽然不寻常,但它会起作用。 - Ohgodwhy
1
非常感谢你,Jasper。我不认为它解决了我的问题,因为存在兼容性问题,但它确实回答了我的问题。感谢你的时间。 - Klaus Byskov Pedersen
1
DOMNodeInserted已被弃用。 - toutpt
@toutpt 谢谢,我已经更新了答案并附上了新API的链接。 - Jasper

10

在阅读以上答案后,我现在成功地使用了以下代码:

$('body').on({
   DOMNodeInserted : function(){
      alert('I have been added dynamically');
   },
   click : function(){
      alert('I was clicked');
   },
   '.dynamicElements'
});

现在所有我的dynamicElements都可以在加载时执行操作,利用了强大的.on()事件映射。

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