0

iframe ナビゲーション中のイベント ハンドラーと DOM 要素の間の参照ループによって引き起こされる IE8 のメモリ リークを取り除こうとしています。ページ上の他のスクリプトを変更できません。

そのため、DOM とウィンドウ オブジェクトを調べ、すべてのフィールドを無効にして、DOM 要素がイベント ハンドラーを参照しないようにするというアイデアがありました。

ここでの問題は、他のすべてのアンロード ハンドラーが実行された後にそれを行う必要があることです。これは、他のハンドラーが無効にするフィールドに依存している可能性があるためです。

親ウィンドウのどこかに移動する前にドキュメント オブジェクトを保存しようとしました。次に、iframe でのナビゲーションが完了した後 (onload イベント)、保存されたドキュメント オブジェクトでクリーンアップを実行しました。しかし、古いページがアンロードされた後、このドキュメントにアクセスすると不正 (アクセス エラー) になるため、それはできないようです。

私が試したもう1つのアプローチは、最後に呼び出されることが保証されるウィンドウアンロードハンドラーを追加する方法を見つけることでしたが、これまでのところ成功していません。それを達成するために、アンロード イベントのすべてのハンドラーを呼び出してクリーンアップし、コードを実行しようとしましたが、アンロード イベントを手動でトリガーする方法が見つかりませんでした。

何か案は?残念ながら、ページは独自のアンロード ハンドラを持つ jQuery と Microsoft Ajax を使用しています。特に、私の無効化は MS Ajax アンロード ハンドラーを破壊します。これは、すべてのライブラリー名前空間が削除されるためです。

4

1 に答える 1

0

そもそもどのようにアタッチされたのかを知らなければ、すべてのイベント リスナーの削除を保証することは不可能だと思います。

IE 8 はattachEventを使用するため、リスナーが次のように追加された場合:

element.attachEvent('onclick', function(){...});

その場合、リスナーが接続されていることを知る方法がありません。onclickプロパティを新しい値 ('' など) に設定しても、リスナーは削除されません。また、 attachEventによって別のリスナーが追加されることもありません。DOM 準拠のブラウザーでは、要素をそれ自体のクローンに置き換えるとリスナーが削除されますが、 attachEVentが使用されている IE では削除されません。

通常、メモリ リークを回避するための戦略には、DOM 要素を含む循環参照を作成しないことが含まれます。

すべてのリスナーを削除するための戦略は、通常、追加されたもののリストを保持し、ページがアンロードされる前に明示的に削除することに依存しています。

ページ内のすべてのコードを制御できない場合、どちらも困難であり、保証することは不可能です。

于 2013-07-31T05:51:37.797 に答える