2016-02-17 3 views
10

私は大規模な単一ページアプリケーションを構築しており、最近JSのメモリリークを調べています。そして、私はChromeでプロファイル(スナップショット)機能を使用しているので、私は分離されたDOM要素がたくさんあることから、メモリリークが発生していると思います。ユーザーがボタンAをクリックした場合シングルページアプリケーションでイベントリスナーをアンバインドして子要素を削除する適切な方法は何ですか?

<div id="container"> 
    <div class="buttons"> 
    <a class=".btn" href="/someurl/"> Button A</a> 
    <a class=".btn" href="/someurl/"> Button B</a> 
    <a class=".btn" href="/someurl/"> Button C</a> 
    </div> 

    <div class="ajaxHolder"></div> 
</div> 

ので、例えば、私は.ajaxHolderにコンテンツをロードするためにAJAX呼び出しを使用します。ここでは

は私の設定の簡略図です。このような何か:

//This is the content... 
<div class="contentA"> 
    <p>some text...</p> 
    <input type="checkbox" class="checkbox"> 
    <input type="checkbox" class="checkbox"> 
    <input type="checkbox" class="checkbox"> 
    <input type="checkbox" class="checkbox"> 
</div> 

私はまた私のMAINスクリプトファイル内の2つの機能を持ちます。 1つはこれのようになります:

//Click event bound to a.btn which tigger the ajax call 
$(.buttons).on('click', '.btn', function(){ 
    //Do ajax here... 
    //on success... 
    var holder = $(".ajaxHolder"); 
    holder.children().off().remove(); // Is this the way to do this?? 
    holder.off().empty(); //I don't think I need .off() here, but I guess it can't hurt... 
    holder.append(ajaxSuccessData); 
}); 

これまでのところとても良いです。しかし、今ロードされたコンテンツに、私も自分のMAINスクリプトファイル内でこの機能をしている:ユーザーがボタンBを押すと

//So here, I am binding an event to the checkboxes... 
$(".ajaxHolder").on('change', '.checkbox', function(){ 
    //Do something... 
}); 

はだから今、例えば、.ajaxHolderが空にされていますが、すべてのこれらのイベントは、私に結び付けチェックボックスは、分離されたDOMツリーに表示されているので、まわりをついているようです。

私はここで何が欠けていますか?このように実行される単一のページアプリケーションで、分離されたDOM要素がないことを確認するにはどうすればよいですか?

ボーナス質問:私はイベントの多くは、このように結ばれてい:私は.ajaxHolderはいつもするので、イベントの委任を使用する必要があるため

$(".ajaxHolder").on('someEvent...','.someClass....', someFunction()); 

言うことです、すべてがいつも、私の.ajaxHolderに取り付けられています。存在しているのですが、ロードされている他のアイテムは必ずしも存在しないので、私は単に$(button).on('click')...などを実行することはできません。

これも正しい方法ですか?この.ajaxHolderに添付できるアイテムの数に制限がありますか、これを行う際に問題はありませんか?

EDIT:これは私のコンソールのイメージです。

enter image description here

+2

jQueryメソッドで要素を削除すると、データがjQueryを使用して関連付けられている限り、関連するすべてのデータを削除することができます。手動でイベントをバインド解除する必要はありません。 –

+0

あなたはajaxHolder上で委譲することができますが、プロジェクトが成長するにつれて簡単に手を出すことができます。また、同じタイプのイベントハンドラが多数バインドされている場合は、パフォーマンスの低下を開始する可能性がありますが、そのパフォーマンスの問題が発生する前に、保守性の問題が発生する可能性があります。 –

+0

@KevinBだから、なぜ分離されたDOM要素が現れていますか?削除されたアイテムへの参照を保持するその他の原因そして、2番目の部分については、それをajaxHolderに委譲する以外に、私は他にどのようなオプションがあるのでしょうか...ドキュメントに委譲できると思いますが、それは単なる旅行であり、問​​題を解決しません。あなたの解決策は何ですか? – Amir

答えて

-1

jQueryのイベントバインド解除と要素の除去、以下の方法で洞ことができます。これを行うための最善の方法は、すべてのバインド解除することです

$.off()

$.remove()

+0

1)don ** e **; 2)これは本当の答えではありません。これは、Web上の2つのリンクへのポインタです。これを改善したい場合は、OPがその目的を達成するためにこれらの機能をどのように使用するかを説明してください。質問に表示されているコードはすでに '.off()'と '.remove()'の両方を持っています。 –

-3

$(selector).off();を使用してイベントリスナーを作成します。 $(selector).remove();を使用して要素を削除します。

これは、イベントハンドラのために起こっているすべてのメモリリークを停止します。

+0

OPにはすでにコード内に 'off()'と 'remove()'があります。これは何も追加しない。 –

1

これはまだ関連していませんが、私があなたが集めたコンソールイメージからは、ブートストラップツールチップを使用しており、DOMノードへの参照を保持しているようです。 API

関連する問題