简短错误的答案:
您可以通过处理
beforeunload事件并返回非null字符串来做到这一点:
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 = /confirm/iationMessage; //Gecko + IE return /confirm/iationMessage; //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 = /confirm/iationMessage; //Gecko + IE return /confirm/iationMessage; //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 = /confirm/iationMessage; //Gecko + IE return /confirm/iationMessage; //Gecko + Webkit, Safari, Chrome etc. });};现在要实现该
isDirty方法,有多种方法。
您可以使用jQuery和表单序列化,但是这种方法有一些缺陷。首先,您必须更改代码才能在任何形式上工作(
$("form").each()会这样做),但是最大的问题是jQueryserialize()只能在命名的,未禁用的元素上运行,因此更改任何禁用或未命名的元素都不会触发脏标志。有一些解决方法,例如将控件设置为只读而不是启用,序列化然后再次禁用控件。
因此,事件似乎是路要走。您可以尝试收听按键。此事件有几个问题:
- 不会触发复选框,单选按钮或通过鼠标输入更改的其他元素。
- 将触发不相关的按键,如
Ctrl
按键。 - 不会触发通过Javascript代码设置的值。
- 通过上下文菜单剪切或粘贴文本不会触发。
- 对于日期选择器或复选框/单选按钮美化器等虚拟输入(通过Javascript将其值保存在隐藏输入中)不起作用。
该
change事件也[不会触发Javascript代码设置的,因此也不适用于虚拟输入。
将
input事件绑定到页面上的所有
inputs(以及
textareas和
selects)在[较旧的浏览器上将无法使用,并且像上述所有事件处理解决方案一样,不支持撤消。当用户更改文本框然后撤消该文本框,或者选中并取消选中一个复选框时,该表单仍被认为是脏表单。
当您想要实现更多的行为时,例如忽略某些元素,您将需要做更多的工作。
不要重新发明轮子:
因此,在考虑实施这些解决方案和所有必需的变通办法之前,请先意识到自己正在重新发明轮子,并且容易遇到其他人已经为您解决的问题。
如果您的应用程序已经使用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即将推出,其中自定义消息也将被删除。
本网站其他地方也有一些替代方法,但我认为这样的对话框很清楚:
您要离开这个网站吗?
您所做的更改可能不会保存。
LeaveStay



