一个元素从DOM中被删除后,他所绑定的事件浏览器是如何处理的?

2026-05-02 12:25:24 430

问题:一个元素从DOM中被删除后,他所绑定的事件浏览器是如何处理的?

回答:https://segmentfault.com/q/1010000008962585

1.使用Node.removeChild(element)ChildNode.remove()并不会直接释放对应的event listener,但是会被gc。如果该dom对象在js中再无其他引用,与之绑定的event listener就会在合理的时机被gc。如果被remove的dom对象没有其他引用,你并不需要手动解绑事件。

element = document.getElementById("xxx");
element.remove();
element = null;  // 对该dom对象的引用数变为0,gc会适时回收该dom对象上的所有event listener

也正是因为dom的删除,不会直接删掉对应的event listener这一特性,才会因为部分早期版本的浏览器(特别是IE)中gc算法的不完善,导致javascript的Memory Leak所以在已经知道要移除dom的时候最好手动移除对应的事件处理程序。

例一:如果span没有重置为null,重新添加后事件依然存在。

var span = document.getElementById('span');
span.addEventListener('click', function () {
    span.parentNode.removeChild(span);
    setTimeout(function () {
        document.body.appendChild(span);
    }, 1000);
});

2.jQuery中的remove方法,会在移除dom元素的同时,调用一个内部函数cleanData将所有子节点及相关的event listener全部移除

例二:移除后再次添加事件已注销

var $span = $('#span');
$span.click(function () {
    $(this).remove();
    setTimeout(function () {
        $('body').append($span);
    }, 1000);
});

3.在匿名函数中移除事件

var btn1 = document.getElementById("btn1");
// 实名函数
var handle1 = function () {
    btn1.removeEventListener("click", handle1, false);
}
btn1.addEventListener('click', handle1, false);

// 匿名函数
var btn2 = document.getElementById("btn2");
btn2.addEventListener("click", function (e) {
    // 在匿名函数中移除事件
    btn2.removeEventListener(e.type, arguments.callee, false);
}, false)

HTML DOM 事件参考文档:http://www.runoob.com/jsref/dom-obj-event.html