Несколько событий onbeforeunload () и onunload () - PullRequest
5 голосов
/ 12 мая 2010

У меня странная проблема с клиентом в том, что наш код, который они включают, использует onbeforeunload () для запуска диалога, но они также включают код другой компании, который также связывает этот обработчик событий.

Возможно ли выполнение обоих одновременно?

Я читал это, http://oreilly.com/catalog/9780596101992 "JavaScript: Полное руководство, пятое издание", чтобы попытаться помочь лучше понять, что происходит во внутреннем пространстве браузера и в стеке javascript, но это доказывает, что это очень сложно .

Из чтения книги я понимаю, что некоторые события могут выполняться одновременно, если они присоединены с помощью API-интерфейса уровня 2 addEventListener (), но порядок будет зависеть от браузера. Однако нет упоминания о событии onbeforeunload (). Просто onunload ().

Что подводит меня ко второй части вопроса. Если событие вызывается в onbeforeunload (), правильно ли я считаю, что если он не вернет true, onunload () никогда не будет вызван?

Если кто-то может пролить некоторый свет на это, или подключить меня к хорошему учебнику / руководству по назначению нескольких обработчиков событий для одного и того же события, или конкретно по этим двум событиям, которые будут асом.

Спасибо

1 Ответ

8 голосов
/ 12 мая 2010

Возможно ли выполнение обоих одновременно?

Не буквально одновременно, нет & mdash; Javascript в браузерах (в настоящее время) является однопоточным. Таким образом, для события onbeforeunload может быть несколько обработчиков, но они будут вызываться последовательно, а не одновременно. По крайней мере, в теории; на практике похоже, что только один из них называется (см. ниже).

Если событие вызывается в onbeforeunload (), прав ли я, полагая, что если он не вернет true, onunload () никогда не будет вызван?

Если какой-либо обработчик onbeforeunload отменяет выгрузку, обработчик onunload вызываться не будет. Вы отменяете выгрузку, выполняя две вещи (потому что браузеры отличаются здесь): сначала вы присваиваете строку свойству returnValue объекта event, а затем возвращаете эту строку из функции. Подробности здесь и здесь . (Строка используется в качестве подсказки, позволяющей пользователю решить, отменить ли выгрузку.)

Быстрый тест

Так много для теории, давайте посмотрим, что на самом деле происходит:

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Test Page</title>
<style type='text/css'>
body {
    font-family: sans-serif;
}
</style>
<script type='text/javascript'>
window.onload = pageInit;
function pageInit() {
    hook(window, 'beforeunload', beforeUnload1);
    hook(window, 'beforeunload', beforeUnload2);
    hook(window, 'unload', unload1);
    hook(window, 'unload', unload2);
}

function beforeUnload1(event) {
    var s;

    event = event || window.event;
    s = "Message from beforeUnload1";
    event.returnValue = s
    return s;
}

function beforeUnload2(event) {
    var s;

    event = event || window.event;
    s = "Message from beforeUnload2";
    event.returnValue = s
    return s;
}

function unload1(event) {
    alert("Message from unload1");
}

function unload2(event) {
    alert("Message from unload2");
}

var hook = (function() {
    var d;

    function hookViaAttachEvent(obj, eventName, handler) {
        obj.attachEvent('on' + eventName, handler);
    }
    function hookViaAddEventListener(obj, eventName, handler) {
        obj.addEventListener(eventName, handler, false);
    }

    d = document.createElement('span');
    if (d.addEventListener) {
        return hookViaAddEventListener;
    }
    else if (d.attachEvent) {
        return hookViaAttachEvent;
    }
    throw "Neither attachEvent nor addEventListener found.";
})();
function hook(eventName, handler) {

}
</script>
</head>
<body></body>
</html>

В Chrome, IE и Firefox я только когда-либо вижу уведомление от одного из onbeforeunload обработчиков, даже когда я говорю, что можно идти вперед и уходить. Я ожидаю, что это, вероятно, потому, что в противном случае достаточно раздражающая страница может просто зарегистрировать кучу обработчиков и продолжать мучить пользователя, чтобы он оставался на странице.

После (одного) вопроса, если я разрешу продолжить навигацию, я получу оба сообщения выгрузки.

...