2011-09-30 55 views
3

比方说,我有一个页面可以动态加载页面。随着每个页面加载到DOM中,该页面中的元素的事件被添加。如果元素被删除,我是否必须清除DOM中的事件?

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

但是,他们是否也被删除?还是他们坐在用户的记忆中,占用空间?

后续: 是一个函数定义为这样:

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

一个可以很容易地event = null(或所以我会承担!)...

但如果删除事件该事件没有保存到本地变量?

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

谢谢!

+0

有关JavaScript垃圾回收的问题中的Noldorin引用:“使用var关键字。在没有var关键字的情况下创建的任何变量都将在全局范围内创建,并且永远不会有资格进行垃圾回收,从而可能导致内存泄漏。 Curses ...所以我必须手动清除它们...(或者至少在创建事件时将它们粘贴到局部变量中...) http://stackoverflow.com/q/864516/ 122353 –

+1

还有一些浏览器版本的旧版本在被移除的元素上发生了资源泄漏(特别是我认为是IE),但是幸好它们已经老了,大部分已经消失/死亡。 –

+1

'event = null'不会删除该事件。它只会删除对用于注册事件的jQuery对象的引用。该事件仍将被注册。 – jasongetsdown

回答

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('*');

干净的方法也摆脱任何事件处理程序和存储附加到div的子元素。

THEN。由mootools添加的事件进入元素存储。元素存储位于元素原始使用的闭包后面的对象中。为了测试它,我们将重新实现它,让它刺穿的(一个全局对象称为存储),这样我们就可以检查父走了之后会发生什么情况参考:

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的垃圾收集和浏览器之间,你很好地被覆盖了。请注意,如果回调是匿名的,您可以在单个元素上堆叠多个事件。

+0

感谢您的冗长答复。看起来我已经严重误导了。现在调查使用'.empty();'。 –

+0

欢迎您,任何问题 - 只需拍摄。 –

1

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

设置为null不会删除事件,它只会删除对事件的引用。你需要使用element.removeEventListener和element.detachEvent(取决于浏览器),或者如果你正在使用jQuery解除绑定应该工作。

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

相关问题