我的应用程序中有一些带有表单的页面。
如何以某种方式保护表单,如果有人离开或关闭浏览器选项卡,则应提示他们确认他们确实要保留未保存的数据?
您可以通过处理beforeunload事件并返回非null字符串来做到这一点:
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方法,有多种方法。
isDirty
您可以使用jQuery和表单序列化,但是这种方法有一些缺陷。首先,您必须更改代码才能在任何形式上工作($("form").each()会这样做),但是最大的问题是jQueryserialize()只能在命名的,未禁用的元素上运行,因此更改任何禁用或未命名的元素都不会触发脏标志。有一些解决方法,例如将控件设置为只读而不是启用,序列化然后再次禁用控件。
$("form").each()
serialize()
因此,事件似乎是路要走。您可以尝试收听按键。此事件有几个问题:
Ctrl
该change事件也[不会触发JavaScript代码设置的,因此也不适用于虚拟输入。
change
将input事件绑定到页面上的所有inputs(以及textareas和selects)在[较旧的浏览器上将无法使用,并且像上述所有事件处理解决方案一样,不支持撤消。当用户更改文本框然后撤消该文本框,或者选中并取消选中一个复选框时,该表单仍被认为是脏表单。
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>
请注意,在此对话框中不支持自定义消息。从上个月开始,Chrome 51即将推出,其中自定义消息也将被删除。
本网站其他地方也有一些替代方法,但我认为这样的对话框很清楚:
您要离开这个网站吗? 您所做的更改可能不会保存。 Leave Stay
您要离开这个网站吗?
您所做的更改可能不会保存。
Leave Stay
Leave
Stay