jQuery使用事件处理程序删除元素
我有一个产品列表,我需要动态更新#container
的innerHTML。
我的问题是,如果我在这个答案中做了类似的事情: Jquery删除元素内的所有事件处理程序
$("#container").find("*").off();
所以,我删除了所有孩子的所有事件处理程序,然后我更新了html:
$("#container").html(responseFromAJAX);
这将如何影响性能? 我的意思是,这是一个好方法,删除所有旧元素和处理程序,清理内存,或者我需要做更多?
我的应用程序是一个网上商店,所以我的用户将环顾四周,并更新#container
可能30-50次/访问。
当DOM元素从DOM中删除时,直接连接到DOM元素的事件处理程序会死亡。
替换内容就足够了。
委派活动是更好的选择:
延迟事件(事件委托)的规则是不同的,因为事件实际上并不连接到单个DOM元素,而是在更高级别(如document
)捕获。 然后运行选择器,并针对匹配元素运行事件函数。 延迟事件占用较少的内存,但运行速度较慢(很快)(您永远不会注意到鼠标事件的差异),因为元素搜索仅在事件触发时完成。
我通常建议使用deferred,而不是连接到许多单独的元素,尤其是当您的DOM元素动态加载时。
例如
$(document).on('someeventname', 'somejQueryselector', function(e){ // Handle the event here });
具有委托处理程序的事件序列
- 将委派的处理程序附加到单个不变的祖先元素(如果没有其他更接近/方便的话,
document
是最好的默认值有几个原因)。 请参阅说明了解详情 - 所选事件会冒泡到委派的目标元素
- jQuery选择器仅适用于bubble-chain中的元素
- 事件处理程序仅针对导致事件的匹配元素运行。
这样做的结果是委托处理程序仅在事件时匹配,因此可以处理动态添加/删除的内容。 在事件注册时,运行时开销实际上较低(因为它只连接到单个元素),并且事件时的速度差异可以忽略不计(除非您可以每秒单击鼠标50,000次!)。
笔记:
- 对于委托事件,您应该尝试将它们附加到单个元素,即元素的祖先,并且不会更改 。
- 如果没有其他方便的话,后备通常是
body
或document
。 - 对委托事件使用
body
可能会导致样式设置出错。 这可能意味着鼠标事件不会冒泡到正文(如果计算出的body
高度为0)。document
更安全,因为它不受样式的影响。 - 此外,
document
始终存在,因此您可以在DOM-ready处理程序之外附加委派的事件处理程序 ,而不会出现任何问题。
你可以像许多其他jQuery方法一样使用html() ,它清理事件处理程序和相关数据(当从DOM中删除元素时,不会自动清除btw)。
$("#container").html(responseFromAJAX);
从文档:
当.html()用于设置元素的内容时,该元素中的任何内容都将被新内容完全替换。 此外,在使用新内容替换这些元素之前,jQuery会从子元素中删除其他构造(如数据和事件处理程序) 。