Захват результата диалогового окна подтверждения window.onbeforeunload

Есть ли способ получить результат диалогового окна подтверждения window.onbeforeunload, подобного приведенному ниже из Stack Overflow (это происходит, когда вы покидаете страницу «Задать вопрос» без публикации вопроса)?

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

window.onbeforeunload диалоговое окно подтверждения

Предположительно, если они все еще находятся на оскорбительной странице после того, как событие было запущено, они решили остаться, и вы, вероятно, могли бы понять это, просмотрев последовательность js. Однако я хотел бы знать, как определить, нажали ли они кнопку "Покинуть эту страницу"?

Я реализовал это, как показано ниже:

// concept taken from SO implementation
function setConfirmUnload(showMessage, message) {
    window.onbeforeunload = showMessage ? (message ? message : "this is a default message") : null;
}

// pseudo code
listen to changes on inputs
if any inputs fire a change event
   call setConfirmUnload(true, 'My warning message')

примечание Я использую jQuery на своем сайте.

По сути, я пытаюсь реализовать реализацию Gmail, подобную черновой реализации, в которой, если пользователь покидает страницу с формой, в которую он внес изменения, без сохранения, он нагревается с помощью аналогичного диалога. Если они решат отказаться от своих изменений и покинуть страницу, мне нужно очистить некоторые временные записи из базы данных (я думаю, вызов AJAX или просто отправить форму с флагом delete), а затем отправить их по пути .

Мой вопрос также касается:

jQuery AJAX вызвать обработчик onunload, запускающий ПОСЛЕ получения страницы при ручном обновлении. Как я могу гарантировать, что onunload произойдет первым?


person xzyfer    schedule 23.03.2011    source источник


Ответы (3)


Вы можете получить подтверждение выхода, используя window.onbeforeunload, но способ узнать, на какую кнопку нажал пользователь.

Чтобы процитировать более ранний ответ от jvenema из этой темы:

Основная цель перед выгрузкой — предоставить пользователям возможность сохранять изменения до того, как их изменения будут потеряны.

Кроме того, если ваши пользователи уходят, уже слишком [...]

person Haochi    schedule 23.03.2011
comment
Чтобы проверить, что нажал пользователь: я нашел успешное решение, используя window.onfocus(). Эта функция будет запущена, когда пользователь нажмет STAY и вернется на страницу. Однако обратите внимание, что onfocus() также будет срабатывать при смене вкладок, окон и т. д. Установите глобальную переменную в onbeforeunload(), чтобы иметь возможность проверять/захватывать, откуда приходит пользователь. Если пользователь ДЕЙСТВИТЕЛЬНО хочет покинуть страницу, вы можете сделать некоторые последние действия в window.onunload() - person GDmac; 02.07.2013
comment
Я обнаружил, что оба эти метода не работают (надежно) при обновлении страницы в firefox 75.0. Тайм-аут, похоже, работает, но он должен быть установлен больше, чем время перезагрузки страницы. Я проверил это, и иногда срабатывал тайм-аут в секунду, что влияло на перезагрузку страницы. - person pietervanderstar; 16.04.2020
comment
еще немного покопался и обнаружил, что время ожидания должно быть больше, чем время, необходимое пользователю, чтобы принять решение, поскольку таймер будет продолжать работать в фоновом режиме. - person pietervanderstar; 16.04.2020

Как насчет этого:

$( window ).bind( 'beforeunload' , function( event ) {
    setTimeout( function() {
        alert( 'Hi againe!' );
    } );
    return '';
} ).bind( 'unload', function( event ) {
    alert( 'Goodby!' );
} );
person dev5er6    schedule 05.06.2013
comment
На самом деле это не совсем так... даже на локальном хосте обычно требуется более одного тика между beforeunload и unload. Даже задержка в 500 мс может быть слишком короткой при медленном соединении. - person Sjeiti; 25.04.2017

Поздно на вечеринку, но я нашел следующий код (на TypeScript) достойным способом определить, нажал ли человек «ОК» в этом диалоговом окне подтверждения.

public listenToUnloadEvents(): void {

  window.addEventListener('beforeunload', (e) => {
    const confirmationMessage = '\o/';

    (e || window.event).returnValue = confirmationMessage;     // Gecko + IE
    return confirmationMessage;                                // Webkit, Safari, Chrome etc.
  });

  window.addEventListener('unload', () => {

    this.sendNotification(Action.LEFT)
  });
}

Я не уверен, сколько времени у вас есть для запуска кода в событии unload, но в этом случае я отправляю уведомление через Socket.io, поэтому оно выполняется очень быстро.

Что касается обнаружения отмены в этом уведомлении, как уже упоминалось, создание глобальной переменной, такой как let didEnterBeforeUnload = false, может быть установлено на true, когда срабатывает событие beforeunload. После этого, создав третье событие, подобное этому (опять же, в TypeScript), вы можете сделать вывод, что пользователь нажимает кнопку «Отмена».

window.addEventListener('focus', (e) => {

  if (didEnterBeforeUnload) {
    console.log('pressed cancel')
  }

  didEnterBeforeUnload = false
});

Однако, как примечание, эти события не будут (iirc) срабатывать, если вы не взаимодействовали со страницей. Поэтому не забудьте щелкнуть или коснуться страницы, прежде чем пытаться уйти во время тестирования.

Я надеюсь, что это поможет кому-то еще!

person mylogon    schedule 04.09.2018