Короткий, неправильный ответ:
Вы можете сделать это, обработав beforeunload
событие и вернув ненулевую строку :
window.addEventListener("beforeunload", function (e) {
var confirmationMessage = 'It looks like you have been editing something. '
+ 'If you leave before saving, your changes will be lost.';
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
});
Проблема этого подхода заключается в том, что отправка формы также запускает событие unload . Это легко исправить, добавив флаг, которым вы отправляете форму:
var formSubmitting = false;
var setFormSubmitting = function() { formSubmitting = true; };
window.onload = function() {
window.addEventListener("beforeunload", function (e) {
if (formSubmitting) {
return undefined;
}
var confirmationMessage = 'It looks like you have been editing something. '
+ 'If you leave before saving, your changes will be lost.';
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
});
};
Затем вызывая сеттер при отправке:
<form method="post" onsubmit="setFormSubmitting()">
<input type="submit" />
</form>
Но читайте дальше ...
Длинный правильный ответ:
Вы также не хотите показывать это сообщение, когда пользователь ничего не изменил в ваших формах . Одним из решений является использование beforeunload
события в сочетании с «грязным» флагом, который вызывает запрос только в том случае, если он действительно актуален.
var isDirty = function() { return false; }
window.onload = function() {
window.addEventListener("beforeunload", function (e) {
if (formSubmitting || !isDirty()) {
return undefined;
}
var confirmationMessage = 'It looks like you have been editing something. '
+ 'If you leave before saving, your changes will be lost.';
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
});
};
Сейчас для реализации isDirty
метода существуют различные подходы.
Вы можете использовать jQuery и сериализацию форм , но у этого подхода есть некоторые недостатки. Сначала вам нужно изменить код, чтобы он работал в любой форме ( $("form").each()
будет работать), но самая большая проблема заключается в том, что jQuery serialize()
будет работать только с именованными, не отключенными элементами, поэтому изменение любого отключенного или безымянного элемента не вызовет грязный флаг. Для этого есть обходные пути , такие как создание элементов управления только для чтения вместо включения, сериализации и повторного отключения элементов управления.
Таким образом, события, кажется, путь. Вы можете попробовать прослушивать нажатия клавиш . Это событие имеет несколько проблем:
- Не будет вызывать флажки, переключатели или другие элементы, которые изменяются с помощью мыши.
- Сработает для нерелевантных нажатий клавиш, таких как Ctrlклавиша.
- Не будет срабатывать при значениях, установленных через код JavaScript.
- Не будет запускаться при вырезании или вставке текста через контекстные меню.
- Не будет работать для виртуальных входов, таких как указатели даты или флажки / кнопки-переключатели, которые сохраняют свои значения в скрытом вводе через JavaScript.
change
Событие также не вызывает на значениях , установленных в коде JavaScript , так и не будет работать для виртуальных входов.
Привязка input
события ко всем input
s (и textarea
s и select
s) на вашей странице не будет работать в старых браузерах и, как и все упомянутые выше решения по обработке событий, не поддерживает отмену. Когда пользователь изменяет текстовое поле, а затем отменяет его, или устанавливает и снимает флажок, форма все еще считается грязной.
А когда вы захотите реализовать больше поведения, например игнорировать определенные элементы, у вас будет еще больше работы.
Не изобретай велосипед
Поэтому, прежде чем задуматься о реализации этих решений и всех необходимых обходных путей, поймите, что вы заново изобретаете колесо и вы склонны сталкиваться с проблемами, которые другие для вас уже решили.
Если ваше приложение уже использует jQuery, вы также можете использовать проверенный, поддерживаемый код вместо собственного и использовать библиотеку третьей стороны для всего этого. JQuery вы уверены? Плагин прекрасно работает, смотрите их демонстрационную страницу . Это так просто, как это:
<script src="jquery.are-you-sure.js"></script>
<script>
$(function() {
$('#myForm').areYouSure(
{
message: 'It looks like you have been editing something. '
+ 'If you leave before saving, your changes will be lost.'
}
);
});
</script>
Пользовательские сообщения не поддерживаются везде
Обратите внимание, что Firefox 4 не поддерживает пользовательские сообщения в этом диалоговом окне. По состоянию на апрель 2016 года развернут Chrome 51, в котором также удаляются пользовательские сообщения .
На этом сайте есть другие альтернативы, но я думаю, что такой диалог достаточно ясен:
Вы хотите покинуть этот сайт?
Внесенные вами изменения не могут быть сохранены.
Leave Stay