window.onbeforeunload не срабатывает в дочернем окне

Я хочу привязать функцию к событию 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. Может ли кто-нибудь увидеть, что я делаю неправильно?


person Fiona - myaccessible.website    schedule 13.11.2009    source источник
comment
исходя из вашего заголовка, вы хотели установить newWind.onbeforeunload? Я также понимаю, что определение onbeforeunload на странице settings.url не вариант?   -  person scunliffe    schedule 13.11.2009


Ответы (2)


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

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

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

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

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

person bobince    schedule 13.11.2009

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

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!'); } );
    ...
}
person Yoni Shalom    schedule 10.01.2011