1

beforeunloadJavascriptで子ウィンドウのイベントに関数をバインドしたい。次のコードがあります。

newWind = window.open(settings.url, "Dialog", "width=" + settings.width + ",height=" + settings.height + ",resizable=" + settings.resizable + ",scrollbars=" + true);

newWind.onunload = function() { alert('test'); }

Firefox では正常に動作しますが、IE7 では失敗します。誰かが私が間違っていることを見ることができますか?

4

2 に答える 2

4
newWind.onunload = function() { alert('test'); }

IE では、何らかの理由で、あるウィンドウ コンテキストから別のウィンドウの on[before]unload に関数を割り当てることができません。を含む他のイベント ハンドラーに外部関数を割り当てることができnewWind.document.body.onunloadますが、これはお勧めできません。

まず、IE のガベージ コレクションはウィンドウ ベースであるため、オープナー ウィンドウを閉じたりナビゲートしたりすると、ポップアップがデッド関数を実行しようとするか、スコープ内のデッド変数を使用して関数を実行しようとし、奇妙な JavaScript エラーが発生します。

2 つ目は、ハンドラーを設定するのに十分なほどポップアップ ドキュメントがロードされたときに、オープナーからはわからないためです。呼び出し直後の時点でopenは、ポップアップ ドキュメントの読み込みがまったく開始されていない可能性があります。この場合、イベント ハンドラを安全に設定することはできません。そのため、onunload ハンドラーを設定する前に短い遅延が必要になり、その間にユーザーがウィンドウを閉じる可能性があります。そして、オープナーはどれだけ遅らせればよいかわかりません。代わりに、子ダイアログは親にコールバックして、準備ができていることを伝える必要があります。子ポップアップが独自のイベントを受け取り、オープナーを呼び出してそれらについて知らせるようにすることをお勧めします。

クロスウィンドウ スクリプティングには無限の落とし穴があります。可能な限り避けるようにしてください。ダイアログの場合、常にページ内要素を使用します。これは、ウィンドウ ポップアップよりもはるかに信頼性が高く、煩わしさがありません。

于 2009-11-13T12:14:17.363 に答える
1

次のハックを使用して、子ウィンドウがいつ閉じられたかを確認しています。

function checkChildWindow(win, onclose) {
    var w = win;
    var cb = onclose;
    var t = setTimeout(function() { checkChildWindow(w, cb); }, 500);
    var closing = false;
    try {
        if (win.closed || win.top == null) //happens when window is closed in FF/Chrome/Safari
        closing = true;        
    } catch (e) { //happens when window is closed in IE        
        closing = true;
    }
    if (closing) {
        clearTimeout(t);
        onclose();
    }
}

function openWindow(url) {  
    ...
    var wnd = window.open(url, "window_name", "[...flags...]");
    checkChildWindow(wnd, function() { alert('child was closed!'); } );
    ...
}
于 2011-01-10T14:43:02.327 に答える