Короткий, неправильный ответ:
Это можно сделать с помощью обработки события 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()
), но самая большая проблема в том, что serialize()
в jQuery будет работать только с именованными, не отключенными элементами, поэтому изменение любого отключенного или безымянного элемента не будетвызвать грязный флаг. Есть обходные пути для этого , такие как создание элементов управления только для чтения вместо включения, сериализации и повторного отключения элементов управления.
Таким образом, события кажутся подходящими.Вы можете попробовать прослушивание нажатий клавиш .Это событие имеет несколько проблем:
- Не будет запускаться на флажках, переключателях или других элементах, которые изменяются с помощью мыши.
- Будет срабатывать для неактуальных нажатий клавиш, таких как Ctrl .
- Не сработает при значениях, заданных с помощью кода JavaScript.
- Не сработает при вырезании или вставке текста через контекстные меню.
- Не будет работать для виртуальных входов, таких как датчики или флажки / кнопки-переключатели, которые сохраняют свои значения в скрытом вводе через JavaScript.
Событие change
также не срабатывает при значениях, заданных из кода JavaScript , поэтому также не работает для виртуальных входов.
Привязка события input
ко всем input
с (и textarea
с и select
с) на вашей странице не будет работать в старых браузерах и, как и все упомянутые выше решения для обработки событий, не поддерживает отмену.Когда пользователь изменяет текстовое поле, а затем отменяет его, или устанавливает и снимает флажок, форма все еще считается грязной.
А когда вы хотите реализовать больше поведения, например, игнорировать определенные элементы, вы будете иметь дажебольше работы.
Не изобретайте колесо:
Итак, прежде чем задуматься о реализации этих решений и всех необходимых обходных путей, поймите, что вы заново изобретаете колесо и вы склонны кстолкнуться с проблемами, которые другие уже решили для вас.
Если ваше приложение уже использует 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 не поддерживает настраиваемые сообщения в этом диалоговом окне.По состоянию на прошлый месяц Chrome 51 выпускается , в котором также удаляются пользовательские сообщения .
Некоторые альтернативы существуют на этом сайте, но я думаю, что такой диалог достаточно ясен:
Вы хотите покинуть этот сайт?
Изменения, сделанные вами, могут быть не сохранены.
Оставить Оставаться