如果元素被删除,我是否必须从DOM中清除事件?

Do I have to clear events from the DOM if an element is removed?

本文关键字:DOM 清除 事件 元素 删除 是否 如果      更新时间:2023-09-26

假设我有一个动态加载页面的页面。当每个页面加载到DOM中时,该页中的元素的事件被添加。

如果用户加载另一个页面,先前加载的元素将从DOM中删除。自然地,由于元素本身不再存在,任何映射到这些元素的事件都不再起作用。

然而,它们也被删除了吗?或者它们是否存在于用户的内存中,占用了空间?

追问:如果函数定义如下:

var event = $('foobar').addEvent('click', function() {
    alert(1);
});

可以很容易地用event = null删除事件(或者我认为是这样!)…

但是如果事件没有保存到一个局部变量呢?

$('foobar').addEvent('click', function() {
    alert(1);
});

谢谢!

首先。怎么啦?这没有意义:

var event = $('foobar').addEvent('click', function() {
    alert(1);
});

并没有像您想象的那样将事件保存到一个局部变量中。它将foobar element object的引用保存到event变量中-大多数mootools元素方法将返回this用于链接,这是元素本身而不是方法的结果(除非它是像'. getstyle '这样的getter)。

则取决于你如何删除元素接下来会发生什么。首先,element.destroy,在这里找到:https://github.com/mootools/mootools-core/blob/master/Source/Element/Element.js#L728

将从dom和内存中删除该元素,并以安全的方式清空它。它将依赖于浏览器的GC来清理,mootools不会为元素本身做任何壮观的GC,但它也会在子节点上运行特殊的clean函数:var children = clean(this).getElementsByTagName('*');

clean方法还清除了附加到div的子元素上的任何事件处理程序和存储空间。

。mootools添加的事件进入元素存储。元素存储在元素原型使用的闭包后面的对象中。为了测试它,我们将重新实现它并使其可穿刺(一个称为storage的全局对象),以便我们可以检查在父对象消失后引用发生了什么:

http://jsfiddle.net/dimitar/DQ8JU/

(function() {
    var storage = this.storage = {}; // make it puncturable
    var get = function(uid){
        return (storage[uid] || (storage[uid] = {}));
    };
    Element.implement({
       retrieve: function(property, dflt){
            var storage = get($uid(this)), prop = storage[property];
            if (dflt != null && prop == null) prop = storage[property] = dflt;
            return prop != null ? prop : null;
        },
        store: function(property, value){
            var storage = get($uid(this));
            storage[property] = value;
            return this;
        },
        eliminate: function(property){
            var storage = get($uid(this));
            delete storage[property];
            return this;
        }

    });
})();
// read it.
var link = document.getElement("a");
var uid = link.uid; // will reference the mootools unique id for it
// add an event handler
link.addEvent("click", function(e) {
    console.log("hi");
    this.destroy();
    // see what's left in storage for that element.
    console.log(storage[uid]);
    // storage should be empty.
    console.log(storage);
});
link.getFirst().addEvent("mouseenter", function() {
   console.log("over");
});
// check to see if it is there via element storage API.
console.log(link.retrieve("events").click);
// check to see if it's there via our puncture
console.log(this.storage[uid]);
// see all events in storage, inc child element:
console.info(this.storage);

这一切证明的是,mootools清理了所有需要清理的东西。只要你不使用任何内联onclick=的东西在你的工作与元素,你会很好。在mootools的垃圾收集和浏览器之间,很好地覆盖了您。请注意,如果回调是匿名的,则可以在单个元素上堆叠多个事件。

有趣的问题…看看这个:https://developer.mozilla.org/en/DOM/element.addEventListener#Memory_issues

使用jQuery删除事件监听器,参见http://api.jquery.com/unbind/

我发现旧版本的IE似乎在添加和删除许多与事件绑定的元素方面存在问题。主要原因是循环引用不能被垃圾收集。您可以在这里找到更多信息:http://msdn.microsoft.com/en-us/library/Bb250448

设置为null不会删除事件,它只会删除对事件的引用。您需要使用这两个元素。removeEventListener和element.detachEvent(取决于浏览器),或者如果你使用jquery, unbind应该可以工作。

此外,还有可用的工具来检测泄漏,这个工作得很好(根据同事):http://blogs.msdn.com/b/gpde/archive/2009/08/03/javascript-memory-leak-detector-v2.aspx