Кратко
Секция статьи "Кратко"Когда пользователь уходит со страницы, мы можем спросить его, точно ли он хочет уйти. За это отвечает обработка события beforeunload
.
Событие происходит перед событием выгрузки страницы unload
.
Как пишется
Секция статьи "Как пишется"window.addEventListener('beforeunload', function () { // ...})
window.addEventListener('beforeunload', function () { // ... })
Как это понять
Секция статьи "Как это понять"Мы все хотя бы раз теряли проделанную работу по какой-либо причине:
- Нетленная классика с зависшим Word и несохранённой курсовой.
- Случайный свайп влево на ноутбуках Apple, который вместо горизонтальной прокрутки возвращает на предыдущую страницу.
- Автор этих строк однажды перепутал
git stash pop
сgit stash drop
😰
Есть страницы, на которых выполняется некоторая работа. Если эта работа не сохраняется, например, в localStorage, стоит защитить пользователя от фрустрации при возможной потере. В этом нам поможет обработка события beforeunload
.
Обработка с помощью addEventListener
:
window.addEventListener('beforeunload', function (event) { // Отменяем поведение по умолчанию event.preventDefault(); // Chrome требует наличия returnValue event.returnValue = '';})
window.addEventListener('beforeunload', function (event) { // Отменяем поведение по умолчанию event.preventDefault(); // Chrome требует наличия returnValue event.returnValue = ''; })
Обработка через определение onbeforeunload
на объекте window
:
window.onbeforeunload = () => false;
window.onbeforeunload = () => false;
Во втором случае необязательно возвращать false
, можно вернуть любое значение, кроме null
и undefined
. Раньше браузеры использовали возвращаемое значение в качестве сообщения, но в современной спецификации данное поведение изменили. Встречали сайты, которые при попытке закрыть страницу показывали сообщения про нигерийских родственников или правоохранительные органы? Потому и изменили.
При обработке этого события браузер покажет всплывающее окно, в котором нужно будет подтвердить своё намерение покинуть страницу. В Яндекс Браузере, например, оно выглядит так:
Как оно выглядит в вашем браузере можно проверить с помощью демо ниже.
На практике
Секция статьи "На практике"🛠 Как бы это очевидно ни звучало, помните, что обработка beforeunload
может отменить уход со страницы. На одном из проектов это использовалось для предотвращения случайного выхода со страницы с анкетой. При этом редирект с этой страницы превращал её в кирпич (видели когда-то такой код — document
? Он пересоздаёт страницу из строки: внешне ничего не меняется, но страница перестаёт быть интерактивной, так как обработчики не воссоздаются), чтобы в момент перехода нельзя было ввести новую информацию или отправить невалидный запрос. Получался сценарий:
- Пользователь пытается уйти со страницы
- Страница превращается в тыкву
- Пользователь отменяет переход и остаётся на окирпиченной странице.
Такие баги довольно сложно дебажить, поэтому будьте аккуратны и просчитывайте все пользовательские сценарии. Более конкретно: не используйте событие beforeunload
для модификации DOM-дерева. Оно нужно не для этого.
🛠 Обрабатывайте beforeunload
только в тех случаях, когда это улучшает пользовательский опыт. Например, защита от потери данных при случайном свайпе — это хорошо, в то время как беспорядочные попытки удержать лишь надоедают и вызывают ассоциации с мошенническими сайтами.