window.onbeforeunload не запускается в дочернем окне - PullRequest
1 голос
/ 13 ноября 2009

Я хочу связать функцию с событием beforeunload дочернего окна в Javascript. У меня есть следующий код:

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

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

Прекрасно работает в Firefox, но не работает в IE7. Кто-нибудь может увидеть, что я делаю не так?

Ответы [ 2 ]

4 голосов
/ 13 ноября 2009
newWind.onunload = function() { alert('test'); }

IE по какой-то причине не позволит вам назначить функцию из одного контекста окна для другого окна при [до] выгрузке. Вы можете назначить стороннюю функцию другим обработчикам событий, включая newWind.document.body.onunload, но это не очень хорошая идея.

Во-первых, поскольку сборка мусора в IE основана на окнах, поэтому при закрытии или перемещении по открывающему окну всплывающее окно будет пытаться выполнить неработающую функцию или функцию с мертвыми переменными в области видимости, что приведет к странным ошибкам JavaScript.

И, во-вторых, потому что вы не знаете из открывателя, когда всплывающий документ загружен достаточно, чтобы можно было установить обработчик. В момент сразу после вызова open всплывающий документ может вообще не начать загрузку, и в этом случае вы не можете безопасно установить на него какие-либо обработчики событий. Таким образом, вам потребуется небольшая задержка перед установкой обработчика onunload, и пользователь может закрыть окно в это время. И новичок не знает, как долго задерживаться; вместо этого, дочерний диалог должен был бы перезвонить родителю, чтобы сказать, что он готов. Лучше, чтобы всплывающее окно ребенка отвечало за получение его собственных событий и звонило новичку, чтобы сообщить ему о них.

Скриптовое окно имеет бесконечные подводные камни. Старайтесь избегать этого везде, где это возможно. Для диалогов всегда используйте элементы на странице, которые намного более надежны и менее раздражают, чем всплывающие окна.

1 голос
/ 10 января 2011

Я использую следующий хак, чтобы узнать, когда дочернее окно было закрыто:

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!'); } );
    ...
}
...