Может ли OnBeforeUnload запускать код, если они принимают диалог?

Я хочу контролировать, насколько легко люди могут покинуть мое приложение. Теперь я знаю, что не могу сделать это полностью; это то, для чего нужны задания cron. Но я хотел бы поймать как можно больше случаев.

Я подумал, что мог бы использовать onBeforeUnload для отображения диалогового окна, предупреждая их об уходе и прося вместо этого нажать кнопку «Выход».

Но потом я узнал, что можно запустить синхронный вызов AJAX (хех) при вызове onBeforeUnload; Преимущество синхронности заключается в том, что браузер будет ждать его завершения, прежде чем продолжить, насколько я понимаю. Таким образом, я мог сообщить серверу, что выхожу из системы, когда они закроют окно. И поскольку он находится в onBeforeUnload, а не в onUnload, все данные все еще существуют, и вызов будет отправлен.

У меня вопрос, можно ли их совместить? Я хотел бы, чтобы всплывающее окно предупреждало их об уходе, а затем, ЕСЛИ они продолжают хотеть уйти, отправьте сообщение о том, что они действительно уходят.

Насколько я понимаю, я не могу этого сделать; Я могу сделать:

  1. Отправить сообщение только
  2. Поставь только диалог
  3. Отправьте сообщение и откройте диалоговое окно

... но я не могу отправить сообщение условно, если они приняли диалоговое окно, верно? Насколько я понимаю, когда они нажимают «ОК, я хочу уйти», сразу же срабатывает onUnload, и к этому моменту уже слишком поздно. И № 3 выше бесполезен, потому что я не хочу отправлять сообщение о том, что они выходят из системы, а затем заставлять их отменять диалог и оставаться на странице.

Можно мне тоже взять свой торт и съесть его? Могу ли я спросить их, хотят ли они уйти, и если да, то отправить сообщение?


person Andrew    schedule 25.06.2010    source источник
comment
Не полагайтесь на onbeforeunload в таких случаях, это небезопасно: это нестандартное событие не поддерживается Opera и поэтому никогда не срабатывает. Кроме того, удаление браузера с помощью диспетчера задач или чего-то еще (команда * nix kill) также не вызывает это событие.   -  person Marcel Korpel    schedule 26.06.2010
comment
Как я сказал в самом начале своего поста, я не собирался полагаться на браузер. Вот для чего нужны задания cron на стороне сервера: отлавливать некрасивые закрытия. Я надеялся сделать это как можно более изящным и поймать как можно больше ситуаций.   -  person Andrew    schedule 26.06.2010


Ответы (1)


Как я уже говорил в комментарии, onbeforeunload не работает в Opera. Однако я попробовал следующий код в Firefox (3.6.3/Linux) и Chromium (5.0.375.70), и он работал более или менее. Однако при закрытии окна или вкладки Chromium отображается окно подтверждения, но в течение секунды окно/вкладка закрывается, даже при нажатии Ok. Кажется, есть тайм-аут для синхронных XMLHttpRequests во время onbeforeunload.

window.onbeforeunload = function () {
    if (confirm("Send unsaved data?"))
        sendData();

};

function sendData() {
    var request = new XMLHttpRequest();
    request.open("POST", "wait.php", false); // false = synchronous request
    request.send('data={"foo":"bar"}');
    if (request.readyState == 4 && request.status == 200)
        alert("Succes!");

}

Обновление. Просто для полноты картины, поскольку я забыл включить wait.php, соединение просто удерживается в течение 10 секунд:

<?php sleep(10); ?>
person Marcel Korpel    schedule 25.06.2010
comment
В любом случае, это, скорее всего, будет использоваться только в FF и IE, я не буду изо всех сил поддерживать Opera и Chrome (это собственное приложение). Но это все равно звучит как-то схематично. Основываясь на том, что я вижу, я думаю, что лучше просто свяжу свою судьбу с cron. (Опять же, не то, чтобы его не существовало в любом случае, я просто хотел посмотреть, как изящно я могу закрыть приложение. Кажется, не слишком много.) - person Andrew; 26.06.2010
comment
@ Эндрю: Действительно. Просто сеть не была предназначена для таких вещей. - person Marcel Korpel; 26.06.2010