移除一个元素是不是也会移除它的事件监听器? [复制]

Posted

技术标签:

【中文标题】移除一个元素是不是也会移除它的事件监听器? [复制]【英文标题】:Does removing an element also remove its event listeners? [duplicate]移除一个元素是否也会移除它的事件监听器? [复制] 【发布时间】:2013-09-29 23:01:00 【问题描述】:

如果您还删除带有removeChild() 的元素,则删除与项目关联的事件?即使使用简单的this.innerhtml ='' 删除该项目?这同样适用于与像 <div onclick="/*this event*/"> </div>? 这样的内联元素相关联的事件。提前致谢。

【问题讨论】:

我只是想知道它们在内存中是否保持不变...... @EL Are you sure? 简而言之,我的 3 个问题的 3 个答案是什么? @EL 好吧,您不能单击已删除的元素,但正如您在我的小提琴中看到的那样,可以返回已删除的元素。如果有对已移除元素的引用,事件处理程序仍会消耗内存。多少,另当别论。如果有一个命名函数来处理一个事件,它也会在删除元素后出现。仅保留对处理程序函数的引用仅消耗几个字节...我对您(和小提琴)的评论只是为了表明removeChild() 不一定会从内存中删除其参数中的元素。跨度> @EL 即使删除父元素的innerHTML 也不行。请检查我对 Krasimir 答案的评论中的链接小提琴。只有当没有引用该元素时,它才真正被删除。 【参考方案1】:

答案是看你有没有引用它。

var d = document.createElement('div');
otherElement.appendChild(d);
otherElement.removeChild(d);
// still have reference to d, it will exist, event listener remains even if it won't be fired.

如果您无法再访问它,则该元素将与侦听器一起被垃圾收集(适用于所有浏览器 > IE6)。

【讨论】:

同样在 IEvar elem = event.srcElement; 这样声明的变量在 IEelem 在删除具有此处理程序的元素时会导致内存泄漏。【参考方案2】:

我做了以下测试:

<div class="wrapper">
    <a href="#">Link</a>
</div>
<script type="text/javascript">
    window.onload = function() 
        var wrapper = document.querySelector(".wrapper");
        var link = document.querySelector("a");
        link.addEventListener("click", function() 
            console.log("click");
        );
        setTimeout(function() 
            wrapper.innerHTML = "";
        , 4000)
    
</script>

并在开发工具中监控结果。加载页面后,附加的事件从 5 变为 6。链接从 DOM 中删除,事件侦听器再次变为 5。

【讨论】:

所以内联事件也被 innerHTML 删除了对吧? @user2809046 Nothing is really removed,如果您仍然对元素有引用,如 Tibos 的回答中所述。如果没有引用,则元素及其成员当然会被删除。 所以你建议我手动删除事件?以及如何内联事件? @user2809046 内联元素也消失了。请注意,没有对元素的引用(例如我的小提琴中的全局but),您只能安全地删除该元素。如果有引用,您可以手动删除事件侦听器,但元素本身仍保留在内存中,无论您将做什么......,除非同时删除引用。 我只是运行相同的测试,但使用内联点击处理程序。处理程序甚至没有被 Chrome 的时间线计算在内,这很有趣。

以上是关于移除一个元素是不是也会移除它的事件监听器? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

操作innerHTML 会移除子元素的事件处理程序? [复制]

jquery-DOM

时间线、事件监听器、清理

jQuery事件委托为动态添加的全部元素移除类名

Jquery 4种移除 清空元素的方法

js 使用事件委托