删除 DOM 元素后我应该调用 jQuery.off 吗?

Posted

技术标签:

【中文标题】删除 DOM 元素后我应该调用 jQuery.off 吗?【英文标题】:Should I call jQuery.off after removing the DOM element? 【发布时间】:2015-02-17 02:11:18 【问题描述】:

我正在通过jQuery.on() 在 DOM 元素上注册一个点击监听器。如果稍后从 DOM 中删除该元素 - 可能是间接的,例如通过$(parent).html(...) 替换一些父级的内容,我还应该通过jQuery.off() 删除我的处理程序吗?

即使元素不再触发任何事件,我也担心潜在的内存泄漏。一旦从 DOM 中删除元素,jQuery 或浏览器是否会处理并丢弃所有已注册的处理程序?

【问题讨论】:

【参考方案1】:

即使元素不再触发任何事件,我也担心潜在的内存泄漏。

这是非常好的问题。要回答您的问题,请查看 $.fn.html implementation。从那里您将了解到html 将尝试清理存储的事件数据:

// Remove element nodes and prevent memory leaks
if (elem.nodeType === 1) 
    jQuery.cleanData(getAll(elem, false));
    elem.innerHTML = value;

所以在这种情况下手动调用.off() 是不必要的。不过..

您需要记住,您永远不应该尝试使用诸如removeChild 或设置innerHTML 之类的本机方法来删除元素,因为在这种情况下肯定会发生内存泄漏(如果存储了一些数据,则事件是由 jQuery 等注册)。在这种情况下,使用.off 方法实际注销事件处理程序更可靠。或者更好地使用事件传播而不是html('') 使用$.fn.remove

【讨论】:

但是为什么浏览器会将这些保存在内存中呢?为什么我们需要明确删除它们? @SubinJacob 因为 jQuery 将 dataevent 数据存储在中间对象中。如果从 DOM 中删除元素,可能会发生相关数据将保留在内部缓存中(例如,您使用 .on 绑定事件,然后使用父级上的 removeChildinnerHTML = '' 删除元素)。 jQuery 的html('')empty()remove() 等请确保从缓存中删除相应的元素数据。 哦,就是这样。那么它只与jQuery有关,与浏览器无关,对吧?如果我们使用纯原生 js 绑定事件就好了。 是的,在这种情况下,这是与 jQuery 相关的特定泄漏。【参考方案2】:

最好在删除节点之前调用 jQuery.off,特别是如果它是一个单页应用程序,其中可能包含许多已注册的事件。

【讨论】:

以上是关于删除 DOM 元素后我应该调用 jQuery.off 吗?的主要内容,如果未能解决你的问题,请参考以下文章

如果你删除了一个 DOM 元素,任何以该元素开始的事件是不是会继续冒泡?

从由外部脚本生成的元素中删除 DOM 元素

我应该在对元素应用多种样式时从 DOM 中分离元素吗?

函数失败后我是不是应该重新调用 API 函数并在 c# 中刷新我的访问令牌?

DOM基础操作

退出我的应用程序并返回后我应该调用哪个生命周期函数