отлов перед подтверждением выгрузки отменен?

Я хочу что-то сделать, когда пользователь покидает страницу, я добавляю этот код

window.onbeforunload = function (e){
   return "You save some unsaved data, Do you want to leave?";
}  

Это приглашение может уведомить пользователя, и пользователь может остаться на странице или уйти. Но я хочу больше знать, уйдет он или нет, и действовать в соответствии с его решением. Я пробовал это,

window.onbeforunload = function (e){
   var event = jQuery.Event(e);
   var result = confirm('want to leave?');
   if (result ==  false){
     //do sth.. 
     event.preventDefault();
   }else{
    //do clean up
   }
} 

Но не получается !! Это всегда уходит!

Может ли кто-нибудь помочь мне в этом?


person Zer001    schedule 10.03.2011    source источник
comment
возможный дубликат stackoverflow.com/questions/1299452/, кстати, ваш acceptrate неприемлем!   -  person Gergely Fehérvári    schedule 10.03.2011
comment
@omnosis может быть похожим, но я хочу указать, когда пользователь решает уйти, но меняет решение.   -  person Zer001    schedule 10.03.2011


Ответы (3)


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

Вы можете добиться чего-то похожего на то, что хотите, выполнив очистку onunload и сделав то, что вы всегда хотите делать onbeforeunload.

person Erik Bakker    schedule 10.03.2011
comment
спасибо, но я хочу точно знать, "пользователь намеревался уйти, но изменил свое решение" - person Zer001; 10.03.2011
comment
@Eric, могу ли я отправить асинхронный запрос при onunload? - person Zer001; 11.03.2011
comment
Да, см. stackoverflow.com/ questions / 1821625 / - person Erik Bakker; 11.03.2011
comment
Эрик, спасибо за ваш ответ - я искал нечто подобное, и вы полностью раскрыли для меня загадку. Не уверен, почему ваш ответ не принимается ... - person fred august; 18.03.2011

Насколько я читал об этом методе на различных форумах браузеров, таких как MSDN, MozillaDev и т. Д., Этот метод не имеет обратных вызовов для OK / Cancel. У вас есть это для диалога подтверждения, но не для этого.

Это реализация безопасности, позволяющая пользователям иметь полное право выбирать, какой веб-сайт им следует просматривать. Кроме того, он не позволяет хакерам блокировать доступ пользователей к своим сайтам.

person saarthak    schedule 10.03.2011

Но я хочу больше знать, уйдет он или нет, и действовать в соответствии с его решением.

Если вы хотите что-то сделать, когда он уйдет, вы можете сделать это в unload событии. Например, как упомянул @Erik Bakker, вы можете отправлять асинхронные события в unload событии.

Однако, если вы хотите узнать, «остался» ли пользователь, то есть отменил ли процесс ухода, есть способ. Это вроде как хакерство, но работает.

const doSomethingWhenUserStays = function doSomethingWhenUserStays() {
  alert('user stayed!!!');
}


window.addEventListener('beforeunload', function onBeforeUnload(e) {
  setTimeout(doSomethingWhenUserStays, 500);
  
  // Dialog text doesn't really work in Chrome.
  const dialogText = 'A dialog text when leaving the page';
  e.returnValue = dialogText;
  return dialogText;
});

Метод doSomethingWhenUserStays будет вызываться каждый раз, но если пользователь покинет страницу, он все равно не увидит, что он выполнял. Он может выполнять асинхронные операции, синхронно, это не имеет особого значения, потому что он находится в пределах setTimeout, следовательно, он находится вне нормального потока onBeforeUnload и не будет мешать ему.

Если вы хотите выполнять это ТОЛЬКО, если пользователь действительно остается на странице, это немного сложнее. Вам нужно будет установить глобальный флаг, который проверяет, достиг ли пользователь разгрузки или нет, и только затем вызывать то, что находится внутри doSomethingWhenUserStays. Рассмотрим следующий пример.

let hasUserLeft = false;

const doSomethingWhenUserStays = function doSomethingWhenUserStays() {
  // Perform the following only if user hasn't left the page
  if (!hasUserLeft) {
    alert('user stayed!!!');
  }
}


window.addEventListener('beforeunload', function onBeforeUnload(e) {
  // It won't perform doSomethingWhenUserStays in 500ms right after this is called,
  // but instead, it will perform it in 500ms after you click "Stay" or "Leave".
  // Therefore, there should be some time for `unload` handler to fire and
  // set `hasUserLeft` flag before `doSomethingWhenUserStays` is called.
  setTimeout(doSomethingWhenUserStays, 500);
  
  // Dialog text doesn't really work in Chrome.
  const dialogText = 'A dialog text when leaving the page';
  e.returnValue = dialogText;
  return dialogText;
});


window.addEventListener('unload', function onUnload() {
  hasUserLeft = true;
});

person emil.c    schedule 31.01.2018
comment
это, похоже, не работает для меня в firefox, возможно, потому, что таймер действительно работает в фоновом режиме, он не ждет, пока они нажмут «Отмена». - person stackers; 31.03.2020
comment
Неплохо подмечено. В таком случае, возможно, стоит попробовать setInterval, который должен срабатывать все время, и когда пользователь остается на странице, вы просто вызываете clearInterval. - person emil.c; 01.04.2020