Вы можете обнаружить гиперссылок кликов, но вы не можете определить, действительно ли пользователь:
- Пытался обновить страницу.
- Попытка закрыть вкладку браузера.
- Попытка закрыть окно браузера.
- Введен другой URL-адрес в строке URL и нажмите enter.
Все эти действия порождают beforeunload
событие на window
, без каких-либо более точной информации о событии.
Для того, чтобы отобразить диалог подтверждения при выполнении выше действий, а не отображать его, когда гиперссылка была нажата, выполните следующие действия:
- Присвоить
beforeunload
событие слушателя к window
, который возвращает текст подтверждения в виде строки, , если только для данной переменной (флага) установлено значение true
.
- Назначить:
click
Событие до document
. Проверьте, был ли нажат элемент a
(event.target.tagName
). Если да, установите флаг true
.
Вы также должны обрабатывать формы представления, назначая слушателя submit
событий в document
.
Ваш код может выглядеть следующим образом:
let disableConfirmation = false;
window.addEventListener('beforeunload', event => {
const confirmationText = 'Are you sure?';
if (!disableConfirmation) {
event.returnValue = confirmationText; // Gecko, Trident, Chrome 34+
return confirmationText; // Gecko, WebKit, Chrome <34
} else {
// Set flag back to false, just in case
// user stops loading page after clicking a link.
disableConfirmation = false;
}
});
document.addEventListener('click', event => {
if (event.target.tagName.toLowerCase() === 'a') {
disableConfirmation = true;
}
});
document.addEventListener('submit', event => {
disableConfirmation = true;
});
<p><a href="https://stacksnippets.net/">google.com</a></p>
<form action="https://stacksnippets.net/"><button type="submit">Submit</button></form>
<p>Try clicking the link or the submit button. The confirmation dialog won't be displayed.</p>
<p>Try reloading the frame (right click -> "Reload frame" in Chrome). You will see a confirmation dialog.</p>
Обратите внимание, что в некоторых браузерах, вы должны использовать event.returnValue
в beforeunload
слушателя, а в других вы используете return
заявление.
См. Также beforeunload
event docs.
Проголосовали за повторное открытие. Связанный дубликат не отвечает на вопрос, но ответы здесь. – Heinzi 2013-01-22 12:50:09
FWIW, я приеду вам в розовом пальце, если вы поместите это поведение в любое приложение, которое мне нужно использовать. Увлечение браузером - это достойное решение этой проблемы. Не можете ли вы просто использовать AJAX или что-то еще и автоматически сохранить свое состояние? – Graham 2013-01-22 13:26:14
Я не согласен с Грэмом - иногда предупреждение/подтверждение - это все, что вам нужно. Предоставлено, что это может (и часто) злоупотреблять сайтами, пытаясь удержать вас от увольнения, но наработанные должным образом его можно очень ценить, например, если вы забыли опубликовать что-то. – devios1 2013-01-23 18:13:35