Запускать код JavaScript при закрытии окна или обновлении страницы?


110

Есть ли способ запустить окончательный код JavaScript, когда пользователь закрывает окно браузера или обновляет страницу?

Я думаю о чем-то похожем на onload, но больше на onclose? Спасибо.

Мне не нравится метод onbeforeunload, который всегда приводит к всплывающему окну подтверждения (оставить страницу / остаться в Mozilla) или (перезагрузить / не перезагружать в Chrome). Есть ли способ выполнить код незаметно?


1
Возможный дубликат: stackoverflow.com/questions/805463/…
1,44 МБ


18
Подождите - это на самом деле НЕ дубликат ... Он хочет знать, как выполнить что-то БЕЗ подсказки пользователю - связанные вопросы задают обратное ...
Филдо

Ответы:


86

Существуют оба варианта: window.onbeforeunloadи window.onunload, которые используются по-разному в зависимости от браузера. Их можно назначить либо установив свойства окна для функций, либо используя .addEventListener:

window.onbeforeunload = function(){
   // Do something
}
// OR
window.addEventListener("beforeunload", function(e){
   // Do something
}, false);

Обычно onbeforeunloadиспользуется, если вам нужно запретить пользователю покидать страницу (например, пользователь работает с некоторыми несохраненными данными, поэтому он / она должны сохранить перед уходом). Насколько я знаю, Operaonunload не поддерживает , но вы всегда можете установить и то, и другое.


У меня это сработало: Firefox (69.0.2) и Chrome (77.0.3865.90)
Фелипе Капарелли

51

Хорошо, я нашел для этого рабочее решение, оно состоит из использования beforeunloadсобытия и последующего возврата обработчика null. Это выполнит требуемый код без всплывающего окна подтверждения. Это выглядит примерно так:

window.onbeforeunload = closingCode;
function closingCode(){
   // do something...
   return null;
}

Надеюсь это поможет.


10
Разве это не срабатывает также при переходе и обновлении (F5)? Если так, то это не совсем ответ на вопрос ...
Jago

1
Не тестировалось, но я думаю, что return false;делает то же самое (т.е. предотвращает поведение по умолчанию), и это более семантически правильно.
collimarco

1
return false по-прежнему будет вызывать диалоговое окно с вопросом, хотите ли вы покинуть страницу или нет. Тестировал на якоре. При возврате null диалоговое окно не всплывало, но оно все еще отображалось в console.log
Рики Стэм

21

Иногда вам может понадобиться сообщить серверу, что пользователь покидает страницу. Это полезно, например, для очистки несохраненных изображений, временно хранящихся на сервере, для того, чтобы пометить этого пользователя как «оффлайн» или для регистрации, когда они завершили свой сеанс.

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

К счастью, теперь у нас есть navigator.sendBeacon(). Используя этот sendBeacon()метод, данные передаются на веб-сервер асинхронно, когда пользовательский агент имеет возможность сделать это, не задерживая выгрузку и не влияя на производительность следующей навигации. Это решает все проблемы с отправкой данных аналитики: данные отправляются надежно, они отправляются асинхронно и не влияют на загрузку следующей страницы. Вот пример его использования:

window.addEventListener("unload", logData, false);

function logData() {
  navigator.sendBeacon("/log.php", analyticsData);
}

sendBeacon()это поддерживается в:

  • Край 14
  • Firefox 31
  • Хром 39
  • Safari 11.1
  • Опера 26
  • iOS Safari 11.4

В настоящее время НЕ поддерживается в:

  • Internet Explorer
  • опера мини

Вот полифилл для sendBeacon () на случай, если вам нужно добавить поддержку неподдерживаемых браузеров. Если метод недоступен в браузере, вместо этого он отправит синхронный запрос AJAX.


Этот вопрос входил в состав дела «Отправить запрос на сервер». Идея заключалась в том, чтобы иметь возможность отслеживать открытые вкладки для каждого пользователя и очищать серверную часть, когда вкладка закрыта.
Питер

@Peter Я включил его для полноты картины, но удалил.
Майк

@Mike, пожалуйста, НЕ удаляйте свой ответ. Он не только завершает выбранный лучший ответ (он должен быть вашим), но также представляет событие, используемое для захвата или закрытия окна
Alex8752

@ Alex8752 Я не удалял свой ответ, я вырезал его часть, не имевшую отношения к вопросу, который вы можете просмотреть здесь .
Майк,

1
@AshokKumar Вы контролируете то, что отправляете на сервер. Если вы хотите отправить что-то с помощью GET, ничто не мешает вам отправить запрос на что-то вроде http://example.com/script.php?token=something&var1=val1&var2=val2помещения этих значений в GET.
Майк

14

версия jQuery:

$(window).unload(function(){
    // Do Something
});

Обновление : jQuery 3:

$(window).on("unload", function(e) {
    // Do Something
});

Спасибо Гарретт


8

В документации предлагается прослушивание события onbeforeunload и / или добавление прослушивателя событий в окне.

window.addEventListener('beforeunload', function(event) {
  //do something here
}, false);

Вы также можете просто заполнить свойства .onunload или .onbeforeunload окна функцией или ссылкой на функцию.

Хотя поведение не стандартизировано для браузеров, функция может возвращать значение, которое браузер будет отображать при подтверждении необходимости покинуть страницу.


7

Вы можете использовать window.onbeforeunload.

window.onbeforeunload = confirmExit;
function confirmExit(){
    alert("confirm exit is being called");
    return false;
}

3

Событие вызывается beforeunload, поэтому вы можете назначить функцию window.onbeforeunload.


-2

Вы можете попробовать что-то вроде этого:

<SCRIPT language="JavaScript">
<!--
function loadOut()
{
window.location="http://www.google.com";
}
//-->
</SCRIPT>

<body onBeforeUnload="loadOut()">

24
Остерегайтесь, люди, читающие это не в древние времена - это древний JS и HTML, и другие предложения здесь намного лучше.
RAnders00
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.