有沒有一種方法來反省DOM節點以查看是否附加了事件處理程序,因此您可以有效編寫安全函數來清除DOM節點而不用擔心內存泄漏由事件處理程序?我希望以通用的方式來做到這一點。自動化事件處理程序在清除DOM節點時刪除兒童
回答
從我看到它可能是不可能的,這裏是從Mozilla的網站報價:
https://developer.mozilla.org/en/DOM/element.addEventListener#Memory_issues
內存問題
document.addEventListener( 「裝載」, 功能(事件){obj.func(event);}, false);
將addEventListener調用到 匿名函數會每次創建一個新的 偵聽器。調用 removeEventListener爲匿名 函數不起作用。一個匿名的 函數會創建一個唯一的對象,每個被調用的時間是 ,它不是一個 對現有對象的引用,儘管它可能會調用一個 。當以這種方式添加事件 聽衆時,請確保它僅添加了一次 ,它是永久性的(可以刪除 ),直到其添加的對象 被銷燬。
如果聽者不是匿名的,你可以這樣做。這裏是YUI庫事件的一段代碼:
/**
* Returns all listeners attached to the given element via addListener.
* Optionally, you can specify a specific type of event to return.
* @method getListeners
* @param el {HTMLElement|string} the element or element id to inspect
* @param sType {string} optional type of listener to return. If
* left out, all listeners will be returned
* @return {Object} the listener. Contains the following fields:
* type: (string) the type of event
* fn: (function) the callback supplied to addListener
* obj: (object) the custom object supplied to addListener
* adjust: (boolean|object) whether or not to adjust the default context
* scope: (boolean) the derived context based on the adjust parameter
* index: (int) its position in the Event util listener cache
* @static
*/
getListeners: function(el, sType) {
var results=[], searchLists;
if (!sType) {
searchLists = [listeners, unloadListeners];
} else if (sType === "unload") {
searchLists = [unloadListeners];
} else {
sType = this._getType(sType);
searchLists = [listeners];
}
var oEl = (YAHOO.lang.isString(el)) ? this.getEl(el) : el;
for (var j=0;j<searchLists.length; j=j+1) {
var searchList = searchLists[j];
if (searchList) {
for (var i=0,len=searchList.length; i<len ; ++i) {
var l = searchList[i];
if (l && l[this.EL] === oEl &&
(!sType || sType === l[this.TYPE])) {
results.push({
type: l[this.TYPE],
fn: l[this.FN],
obj: l[this.OBJ],
adjust: l[this.OVERRIDE],
scope: l[this.ADJ_SCOPE],
index: i
});
}
}
}
}
return (results.length) ? results : null;
},
,你可以在這裏閱讀更多: http://developer.yahoo.com/yui/event/
這要看情況。由el.onclick = ...
等屬性指定的簡單事件處理程序可以被有效移除,但是沒有通過attachEvent()
在IE中添加的處理程序列表。在其他瀏覽器中,Memory leaks並不是什麼大問題。
/**
* The purge function takes a reference to a DOM element as an argument.
* It loops through the element's attributes. If it finds any functions,
* it nulls them out. This breaks the cycle, allowing memory to be reclaimed.
* It will also look at all of the element's descendent elements, and clear
* out all of their cycles as well.
* - http://javascript.crockford.com/memory/leak.html
*/
function purge(d) {
var a = d.attributes, i, l, n;
if (a) {
l = a.length;
for (i = 0; i < l; i += 1) {
n = a[i].name;
if (typeof d[n] === 'function') {
d[n] = null;
}
}
}
a = d.childNodes;
if (a) {
l = a.length;
for (i = 0; i < l; i += 1) {
purge(d.childNodes[i]);
}
}
}
如果你想處理這兩種情況下,你管理你的頁面的所有事件處理程序,你可以在自己的功能包addEvent
功能,並刪除它們時的元素將被刪除。
我有這個鬼鬼祟祟的懷疑,沒有辦法從使用Firebug並查看DOM節點上的屬性來獲取附加處理程序的列表。如果頁面以這種方式進行編碼,那麼屬性方法是一個很好的選擇,我傾向於遵循Nick Zakas對此的建議,並避免使用屬性內聯事件處理程序。 – JGFMK 2010-11-04 10:48:50
不要誤解我的意思。我從來沒有建議使用屬性作爲事件處理程序。實際上最後一句話是我答案的本質。 **如果**控制頁面上的所有事件,則可以非常容易地**包裝事件處理,因此從給定節點中刪除事件處理程序應該不成問題。通過包裝我的意思是這樣的:http://dean.edwards.name/weblog/2005/10/add-event/,我想我的答案是非常完整的東西是在這裏被問。 – galambalazs 2010-11-04 21:52:59
- 1. 刪除兒童的事件處理程序
- 2. 刪除兒童事件處理程序,但不是與jQuery自我
- 3. 節點刪除和事件處理程序
- 4. 刪除並讀取元素後,兒童處理程序消失
- 5. 清除每個事件處理程序
- 6. 點擊事件排除兒童(backbone.js)
- 7. 刪除事件處理程序
- 8. 未刪除React事件處理程序
- 9. 刪除的事件處理程序
- 10. C#刪除事件處理程序
- 11. FileSystemWatcher刪除事件處理程序
- 12. 刪除事件處理程序
- 13. 刪除事件處理程序
- 14. 清除兒童元素
- 15. 刪除/殺死/刪除UserControl及其事件處理程序
- 16. 刪除除分支以外的所有DOM兒童PHP
- 17. 如何僅在Backbone.js事件處理程序中指定兒童?
- 18. 從DOM中刪除節點
- 19. 刪除/重置DOM節點
- 20. 從StackPanel中刪除兒童
- 21. Zookeeper不清理已刪除的節點
- 22. 檢測DOM節點何時被刪除?
- 23. 事件處理程序不會自行刪除?
- 24. 從Array刪除兒童作品...有時
- 25. 的NodeJS:兒童事件處理
- 26. 如何清除事件處理在C#
- 27. 如何從事件中刪除所有事件處理程序?
- 28. 如何從應用程序中刪除事件處理程序?
- 29. Drupal 7的孤兒節點引用時刪除節點
- 30. Android兒童點擊事件?
乾杯。底部的YDN鏈接更有意義。我猜你必須使用YUI名稱空間的addEventListener,並且我假設這通過用一系列偵聽器來增加節點來跟蹤偵聽器。 – JGFMK 2010-11-04 11:00:22