10

インライン JavaScript イベントを HTML 要素から完全にバインド解除するにはどうすればよいですか?

私はもう試した:

  • body 要素からのイベントの委譲解除
  • 要素からイベントのバインドを解除します
  • HTML要素からイベント属性を削除することさえあります

少なくとも驚いたことに、onchange属性 ( .removeAttr('onchange')) を削除するだけで、イベントが再び発生するのを防ぐことができました。

<input type="text" onchange="validateString(this)"></input>

これがデリゲートで可能であることはわかっています。おそらくそれが最善の方法ですが、ここでは一緒に遊んでください。この例は、質問を提案するためだけの純粋な仮説です。


したがって、仮説的な状況は次のとおりです。

次のように、インライン HTML 属性を介して入力フィールドに関連付けられた JavaScript イベントを持つ JavaScript 検証ライブラリを作成しています。

<input type="text" onchange="validateString(this)"></input>

しかし、イベントのバインドを解除してライブラリを少し改善したいと考えています。これにより、シングルページ アプリケーションでこのライブラリを使用するユーザーがイベント ハンドラーを管理する必要がなくなり、散らかる必要がなくなります。私の仮想検証ライブラリの関数に入力イベントを接続することにより、コードをまったく. それはどれも真実ではありませんが、まともなユースケースのようです.

Hypothetical Validation Library.js の「サンプル」コードは次のとおりです。

http://jsfiddle.net/CoryDanielson/jwTTf/


テストするには、テキスト ボックスに入力し、他の場所をクリックして変更イベントを発生させます。これは、Web インスペクタを開いて [タイムライン] タブで記録した状態で行います。変更イベントを発生させた (変更イベントを複数回発生させた) 時期に関連するタイムラインの領域を強調表示すると、イベント リスナー (下のウィンドウ内) が変更イベントごとに 100 ずつ増加することがわかります。適切に管理および削除された場合、新しい入力をレンダリングする前に各イベント リスナーが適切に削除されますが、インライン JavaScript イベントでそれを適切に行う方法が見つかりませんでした。

そのコードが行うことは次のとおりです。

  1. onChange、input 要素が検証関数をトリガーする
  2. その関数は入力を検証し、成功した場合は境界線に色を付けます
  3. 次に、(メモリ リークを示すために) 1 秒後に、入力要素が同じ HTML に 100 回続けて置き換えられます。これは、単一ページ アプリ内のビューの変更をシミュレートします。これにより、DOM に 100 個の新しい eventListeners が作成され、Web インスペクタから表示できます。

    • 興味深いメモ。$('input').removeAttr('onchange');onchange イベントが今後発生するのを実際に防ぎますが、Web インスペクタに表示される eventListener/DOM の内容をガベージ コレクションしません。

このスクリーンショットは、変更イベントが 3 回発生した後のものです。毎回、100 個の新しい DOM ノードが同一の HTML でレンダリングされます。HTML をonchange置き換える前に、各ノードからイベントのバインドを解除しようとしました。

ここに画像の説明を入力


更新:この質問に戻って、JSFiddle を使用して簡単なテストを行い、回答が有効であることを確認しました。私は「テスト」を何十回も実行してから待ちました。

ここに画像の説明を入力

4

2 に答える 2

3

あなたが心配することは何もないと思います。メモリは参照できなくなり、最終的にガベージ コレクションが行われますが、Web インスペクタのメモリ ウィンドウには引き続き表示されます。GC がメモリをガベージ コレクションすることを決定すると、メモリはガベージ コレクションされます (たとえば、ブラウザのメモリが不足している場合や一定時間後に)。詳細は GC 実装者次第です。これは、Web Insepctor ウィンドウの下部にある [ガベージを収集] ボタンをクリックするだけで確認できます。Chrome 23 を実行していますが、検証ボックスにテキストを 5 ~ 6 回入力した後、明らかにガベージ コレクションが原因で、メモリ使用量がクラッシュします。

この現象は、インライン イベントに固有のものではありません。大規模な配列を繰り返し割り当ててから、その大規模な配列への参照を上書きし、GC 用に多くの孤立したメモリを残して、同様のパターンを見ました。メモリがしばらく増加すると、GC が開始され、その仕事が行われます。

于 2013-02-09T07:36:38.723 に答える
0

私の最初の提案は使用することoff('change')でしたが、あなたはすでにそれを試したようです. 機能しない理由は、ハンドラーが.on('change'). jQueryがこのようなリスナーを内部でどのように処理するかについてはあまり知りませんが、.on('change', function ()...or.bind('change', function ()...代わりにアタッチしてみてください。

于 2013-02-09T07:21:03.387 に答える