私は大きな問題になるために爆発する小さな迷惑に遭遇しました。
問題1:window.open
Internet Explorerで、(を介して開いた)ウィンドウを閉じると、ウィンドウもownerDocument
一緒に消えます。
これは、またはなどのDOMの呼び出しが、appendChild
またはcreateElement
で失敗することをSCRIPT70: Permission Denied
意味しSCRIPT1717: The interface is unknown
ます。
Chromeなどの他のブラウザの動作を見てきました。ChromeではownerDocument
まだ参照して#document
いownerDocument.defaultView
ますが、最終的にはになりますundefined
。これは私には理にかなっています。を呼び出して通過しますappendChild
。直接createElement
参照しない限り、すべて問題ないと思います。defaultView
問題2: Internet Explorerで、生成されたウィンドウの閉じるボタンをクリックすると、イベントループを尊重していないようです。unload
生成されたウィンドウにイベントをアタッチすると、イベントループの最後でキューに入れるのではなく、すぐに発生します。これは私には意味がありません。このかなり些細な問題に対処することはまったく不可能になります。
問題1が発生したばかりの場合は、-それでも苦痛ですが-簡単な解決策があります。存在するかどうかを確認し、ownerDocument
存在しない場合はスキップします。ownerDocument
同期JavaScriptコードの途中で消えてしまいます。
期待される動作: DOMノードを参照した場合、DOMノードが消えることはありません-ガベージコレクションの健全性。
予想される動作2: DOMノードは同期コードで消えてはなりません。(もちろん削除しない限り)。
既知の回避策: DOMと対話するすべてのコードをウィンドウに移動します。これにより、ウィンドウが閉じられると、JavaScriptランタイム環境も閉じられます。これは簡単な解決策ではなく、アーキテクチャに大幅な変更が必要になる場合があります。
安っぽい解決策: DOMと相互作用する関数を、要素のウィンドウが閉じられたことを検出した場合にエラーを消費する関数にラップします。これは非常に侵襲的であり、パフォーマンスに大きな影響を及ぼし、IEはすでに非常に低速です。
より良い解決策はありますか?
少なくとも、ユーザーがウィンドウを閉じたためにスローされたを無視する方法が必要です。問題1と問題2は、JavaScriptコードに関する基本的な仮定であるガベージコレクションとイベントループを破っています。Error
デモスクリプト
<script type="text/javascript">
function go() {
var popup = window.open('', 'open', 'width=500,height=300,scrollbars=yes,resizable=yes');
popup.document.open();
popup.document.write('<html><head></head><body></body></html>');
popup.document.close();
for (var i = 0; i < 10000; i += 1) {
var node = popup.document.createTextNode(i + " ");
popup.document.body.appendChild(node);
}
}
</script>
<input type="button" onclick="go();" value="Open popup" />
(.htmlファイルとして保存)
指示:
- InternetExplorer9で開く
- 「ポップアップを開く」をクリックします
- レンダリング中にウィンドウを閉じます
- 「許可が拒否されました」を確認します
これがJSFiddleです:http://jsfiddle.net/C9p2R/1/