イベント ハンドラーがアタッチされているかどうかを確認するために dom ノードをイントロスペクトする方法はありますか?イベント ハンドラーによって残されたメモリ リークを心配することなく、dom ノードをクリアする安全な関数を効果的に作成できますか? 私はこれを一般的な方法で行うことを望んでいました。
2 に答える
場合によります。のようなプロパティによって割り当てられた単純なイベント ハンドラーel.onclick = ...
は効果的に削除できますが、 IEattachEvent()
経由で追加されたハンドラーのリストはありません。他のブラウザでは、メモリ リークはあまり問題になりません。
/**
* 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
私が見たところ、それは不可能かもしれません.mozillaサイトからの引用は次のとおりです。
https://developer.mozilla.org/en/DOM/element.addEventListener#Memory_issues
メモリの問題
document.addEventListener("ロード", 関数(イベント) { obj.func(イベント); }, 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/