在离开包含未保存更改的网页之前警告用户
我的应用程序中有一些带有表单的页面。
如何保护表单,以便如果有人离开或关闭浏览器选项卡,应提示他们确认是否确实要将未保存的数据留在表单中?
我的应用程序中有一些带有表单的页面。
如何保护表单,以便如果有人离开或关闭浏览器选项卡,应提示他们确认是否确实要将未保存的数据留在表单中?
您可以通过处理 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.
});
此方法的问题在于,提交表单也会触发卸载事件。通过添加您要提交表单的标志,可以轻松解决此问题:
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.
});
};
然后在提交时调用 setter:
<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 和表单序列化,但这种方法存在一些缺陷。首先,您必须更改代码以在任何形式上工作(将可以),但最大的问题是jQuery仅适用于命名的,非禁用的元素,因此更改任何已禁用或未命名的元素都不会触发脏标志。有一些解决方法,例如使控件只读,而不是启用,序列化,然后再次禁用控件。$("form").each()
serialize()
因此,事件似乎是要走的路。您可以尝试侦听按键。此事件存在一些问题:
更改
事件也不会在从 JavaScript 代码设置的值上触发,因此也不适用于虚拟输入。
将输入
事件绑定到页面上的所有输入
s(以及 textarea
s 和 select
s)在较旧的浏览器上不起作用,并且与上面提到的所有事件处理解决方案一样,不支持撤消。当用户更改文本框,然后撤消该文本框,或者选中并取消选中复选框时,表单仍被视为脏表单。
当你想要实现更多的行为,比如忽略某些元素时,你将有更多的工作要做。
因此,在考虑实施这些解决方案和所有必需的解决方法之前,请意识到您正在重新发明轮子,并且您容易遇到其他人已经为您解决的问题。
如果您的应用程序已经使用jQuery,那么您也可以使用经过测试的,维护的代码,而不是滚动自己的代码,并使用第三方库来完成所有这些工作。
jquery.dirty(由@troseman在注释中建议)提供了用于正确检测表单是否已更改的功能,并防止用户在显示提示时离开页面。它还具有其他有用的功能,例如重置表单,以及将表单的当前状态设置为“干净”状态。用法示例:
$("#myForm").dirty({preventLeaving: true});
一个较旧的,目前被遗弃的项目是jQuery的Are You Sure?插件,它也很好用;查看他们的演示页面。用法示例:
<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>
请注意,自2011年以来,Firefox 4在此对话框中不支持自定义消息。自 2016 年 4 月起,Chrome 51 正在推出,其中自定义消息也被删除。
本网站其他地方存在一些替代方案,但我认为这样的对话已经足够清晰了:
你想离开这个网站吗?
您所做的更改可能不会保存。
Leave Stay
查看 JavaScript onbeforeunload 事件。它是Microsoft引入的非标准JavaScript,但它适用于大多数浏览器,并且它们的onbeforeunload文档有更多信息和示例。