回答:
プレーンJavaScript
削除されたDOM要素が参照なし(それを指す参照がない)の場合、はい -要素自体は、ガベージコレクターとそれに関連するイベントハンドラー/リスナーによってピックアップされます。
var a = document.createElement('div');
var b = document.createElement('p');
// Add event listeners to b etc...
a.appendChild(b);
a.removeChild(b);
b = null;
// A reference to 'b' no longer exists
// Therefore the element and any event listeners attached to it are removed.
しかしながら; まだその要素を指す参照がある場合、要素とそのイベントリスナーはメモリに保持されます。
var a = document.createElement('div');
var b = document.createElement('p');
// Add event listeners to b etc...
a.appendChild(b);
a.removeChild(b);
// A reference to 'b' still exists
// Therefore the element and any associated event listeners are still retained.
jQuery
jQueryの関連メソッド(などremove()
)がまったく同じように機能すると想定するのは公平remove()
です(removeChild()
例として、
ただし、これは正しくありません。jQueryライブラリには、DOMからの削除時に要素に関連付けられたすべてのデータ/イベントを自動的にクリーンアップする内部メソッド(ドキュメント化されておらず、理論的にはいつでも変更できる)が呼び出されますcleanData()
(これはこのメソッドの外観です)。 (これは、を介してもremove()
、empty()
、html("")
など)。
古いブラウザ、特にIEの古いバージョンは、イベントリスナーが接続されている要素への参照を保持しているため、メモリリークの問題があることがわかっています。
従来のIEバージョンのメモリリークを修正するために使用された原因、パターン、およびソリューションの詳細な説明が必要な場合は、Internet Explorerのリークパターンの理解と解決に関するこのMSDNの記事をよくお読みください。
これに関連するいくつかの記事:
この場合、手動でリスナーを手動で削除することをお勧めします(メモリがアプリケーションに不可欠であり、実際にそのようなブラウザーを対象にしている場合のみ)。
remove
メソッドを使用する場合のみです。ほとんどの場合、DOMは完全に消去されます。(ターボリンクか何かのように)。私は私がしなければ、メモリがどのように影響されるか疑問に思ってdocument.body.innerHTML = ''
...
jQueryに関して:
.remove()メソッドは、DOMから要素を取り出します。要素自体だけでなく、要素内のすべてを削除する場合は、.remove()を使用します。要素自体に加えて、要素に関連付けられたすべてのバインドされたイベントとjQueryデータが削除されます。データとイベントを削除せずに要素を削除するには、代わりに.detach()を使用します。
リファレンス:http : //api.jquery.com/remove/
jQuery v1.8.2 .remove()
ソースコード:
remove: function( selector, keepData ) {
var elem,
i = 0;
for ( ; (elem = this[i]) != null; i++ ) {
if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
if ( !keepData && elem.nodeType === 1 ) {
jQuery.cleanData( elem.getElementsByTagName("*") );
jQuery.cleanData( [ elem ] );
}
if ( elem.parentNode ) {
elem.parentNode.removeChild( elem );
}
}
}
return this;
}
どうやらjQueryは node.removeChild()
これによると:https : //developer.mozilla.org/en-US/docs/DOM/Node.removeChild、
The removed child node still exists in memory, but is no longer part of the DOM. You may reuse the removed node later in your code, via the oldChild object reference.
つまり、イベントリスナーは削除される可能性がありますが、node
それでもメモリ内に存在します。
removeChild
ません。どちらも、後者を再アタッチする(この場合は明らかにメモリ内に残る)か、ウェイをスローする(この場合は最終的にGCによってピックアップされて削除される)ために保持できる参照を返します。
ヒープを監視して、クロージャーで要素への参照を保持するイベントハンドラーと、イベントハンドラーへの参照を保持する要素でメモリリークを確認することをためらわないでください。
ガベージコレクターは循環参照を好みません。
通常のメモリリークの場合:オブジェクトに要素への参照があることを認めます。その要素にはハンドラーへの参照があります。そして、ハンドラーはオブジェクトへの参照を持っています。オブジェクトには他の多くのオブジェクトへの参照があります。このオブジェクトは、コレクションから参照解除することで破棄したと考えられるコレクションの一部でした。=>オブジェクト全体とそれが参照するすべてのものは、ページが終了するまでメモリに残ります。=>あなたはあなたのオブジェクトクラスのための完全な殺害方法について考えるか、例えばmvcフレームワークを信頼する必要があります。
さらに、Chrome開発ツールの保持ツリーの部分を使用することをためらわないでください。
他の答えを拡張するだけ...
委任されたイベントハンドラーは、要素の削除時に削除されません。
$('body').on('click', '#someEl', function (event){
console.log(event);
});
$('#someEL').remove(); // removing the element from DOM
今チェックしてください:
$._data(document.body, 'events');
はい、ガベージコレクターもそれらを削除します。ただし、レガシーブラウザでは常にそうであるとは限りません。