8

さまざまなフォーム要素にさまざまなイベントリスナーを添付したとします。後で、私はフォーム全体を削除したい。javascriptのイベントリスナーは、接続先の要素を削除する前に削除する必要がありますか?

は、それが形とその要素に存在するすべてのイベントハンドラの登録を解除するために必要な(または推奨さ)ですか?そうであれば、要素のコレクションですべてのリスナーを削除する最も簡単な方法は何ですか?そうしないことの反響は何ですか? Prototypeを使用しています。

ここに私が実際にやっていることがあります。私はこのように、簡単なフォームを持っている:

<form id="form"> 
    <input type="text" id="foo"/> 
    <input type="text" id="bar"/> 
</form> 

私は例えば、入力に様々なイベントを守ってください。

$('foo').observe('keypress', onFooKeypress); 
$('bar').observe('keypress', onBarKeypress); 

など

フォームはAJAXを経由して送信され、応答がありますフォームの新しいコピー。私は古いフォームを新しいもののコピーで置き換えて、$('form').replace(newForm)のようにしています。私はイベントクラフトの束を蓄積していますか?

答えて

3

うん、ちょっと。巨大な問題ではありませんが、IEの古いバージョンはそのような状況では漏れてしまいます。プロトタイプ1.6.1のよう

(現在はその最終リリース候補で)、ライブラリーは、ページのアンロードにこのクリーンアップを処理します。 Prototypeを使用してイベントオブザーバを追加すると、その要素への参照が配列内に保持されます。ページがアンロードされると、その配列をループしてオブザーバーをすべて削除します。

ユーザーはしばらくの間、このページに滞在しようとしている場合は、メモリ使用量は、ページの期間にわたって蓄積されます。

  1. は、フォーム、交換されることは決してありません1の祖先上のイベントのために聞く:あなたはいくつかのオプションがあります。次に、あなたのハンドラで、イベントがどこから来たのか確認してください。 (すなわち、「イベント委譲」)

  2. 明示的にElement#replaceを呼び出す前に、すべての通話を登録解除します。あなたの例では、あなたは何だろう:

    $('foo', 'bar').each(Element.stopObserving); 
    

これは、与えられた要素にすべてハンドラを除去する効果が引数なし、とのstopObservingを呼び出すのと同じです。

私はオプション1

(私たちはElement#updateElement#replaceの一環として、プロトタイプの将来のバージョンで自動リスナーの除去を行うことについて話しましたが、それはパフォーマンスのトレードオフです。)

をお勧めします
4

登録されていないイベントは、自動的にメモリを解放しないことがあります。これは、IEの古いバージョンでは特に問題です。

プロトタイプは、この自動ガベージコレクションシステムを持っていたが、この方法は、バージョン1.6で削除されました。これは文書番号hereです。メソッドの削除によってガーベジコレクションがもう行われなくなったかどうか、あるいはメソッドが公に利用できなくなったかどうかはわかりません。また、ページのアンロード時にのみ呼び出されたことにも注意してください。つまり、AJAXやDOMの更新を頻繁に行っている間に同じページに長期間滞在すると、その1ページの訪問中にもメモリが許容範囲を超えて漏れる可能性があります。

0

それはジョナスは、下記のシナリオの場合にはDOMから削除される要素からイベントリスナーを削除するには、常に良いことです。

関連する問題