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次!)。

笔记:

  • 对于委托事件,您应该尝试将它们附加到单个元素,即元素的祖先,并且不会更改
  • 如果没有其他方便的话,后备通常是bodydocument
  • 对委托事件使用body可能会导致样式设置出错。 这可能意味着鼠标事件不会冒泡到正文(如果计算出的body高度为0)。 document更安全,因为它不受样式的影响。
  • 此外, document 始终存在,因此您可以在DOM-ready处理程序之外附加委派的事件处理程序 ,而不会出现任何问题。

你可以像许多其他jQuery方法一样使用html() ,它清理事件处理程序和相关数据(当从DOM中删除元素时,不会自动清除btw)。

 $("#container").html(responseFromAJAX); 

从文档:

当.html()用于设置元素的内容时,该元素中的任何内容都将被新内容完全替换。 此外,在使用新内容替换这些元素之前,jQuery会从子元素中删除其他构造(如数据和事件处理程序)