如何让jQuery代码对DOM加载后生成的动态元素生效?
解决动态DOM元素事件绑定失效的问题
这问题我太熟了——你原来的代码之所以对Ajax生成的动态元素无效,核心原因是:直接绑定事件的方式只能作用于执行代码时已经存在于DOM中的元素。那些Ajax加载的元素在你运行hold_trigger.mousedown(...)的时候还没被创建出来,自然没被绑定上事件。
解决方案:用jQuery事件委托(.on()方法)
事件委托利用了DOM的事件冒泡机制,把事件绑定到一个静态存在的父元素(比如document,或者更接近目标元素的容器)上,然后指定要监听的目标选择器。这样不管元素是一开始就有,还是后来动态生成的,只要匹配选择器,事件触发时都会被捕获到。
修改后的代码可以这样写:
var doc = $(document); // 把目标选择器抽出来,方便维护 var triggerSelector = '.qandacontent, tr[id^="comment-"], div[class] > p:not([class])'; // 用.on()绑定事件委托 doc.on({ mousedown: function() { timeout_id = setTimeout(menu_toggle.bind(this), hold_time); }, mouseup: function() { clearTimeout(timeout_id); }, mouseleave: function() { clearTimeout(timeout_id); } }, triggerSelector);
为什么这样可行?
当动态生成的元素触发mousedown、mouseup或mouseleave事件时,事件会向上冒泡到我们绑定了事件的document元素。这时jQuery会检查事件的源头元素是否匹配triggerSelector,如果匹配,就会执行对应的处理函数——完美覆盖动态生成的元素。
小优化建议
如果这些动态元素都有一个固定的、初始就存在的父容器(比如某个带ID的div),建议把事件绑定到这个父容器上,而不是document。这样可以减少事件冒泡的层级,提升一点性能。比如:
// 假设父容器的ID是qanda-container $('#qanda-container').on({ // 事件处理函数和上面一样 }, triggerSelector);
内容的提问来源于stack exchange,提问作者Martin AJ
相关产品推荐
相关产品推荐

