2011-09-30 170 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

相關問題