问题描述
我的应用程序中有一些带有表单的页面。
如何确保表单的安全,如果有人导航或关闭浏览器标签,则应提示他们确认他们确实想要离开表单与未保存的数据?
简短的,错误的答案:
可以通过:
$ p $ window.addEventListener(beforeunload,function( e){
var confirmationMessage ='它看起来像你一直在编辑的东西''
+'如果你在保存之前离开,你的改变将会丢失。';
e || window.event).returnValue = confirmationMessage; // Gecko + IE
返回confirmationMessage; // Gecko + Webkit,Safari,Chrome等
});
这种方法的问题在于提交表单也触发卸载事件 STRONG>。这可以通过添加您提交表单的标志来轻松解决:
var formSubmitting = false;
var setFormSubmitting = function(){formSubmitting = true; };
window.onload = function(){
window.addEventListener(beforeunload,function(e){
if(formSubmitting){
return undefined; $ '
$ b var confirmationMessage ='看起来你一直在编辑某些东西。'
+'如果你在保存之前离开,你的改变将会丢失。';
(e || window.event).returnValue = confirmationMessage; // Gecko + IE
返回confirmationMessage; // Gecko + Webkit,Safari,Chrome等
});
};
然后在提交时调用setter:
< form method =postonsubmit =setFormSubmitting()>
< input type =submit/>
< / form>
但请继续阅读...
长,正确的答案:
当用户没有更改表单上的任何内容时,您也不希望显示此消息。一种解决方案是将 beforeunload
事件与脏标志结合使用,该标志仅在真正相关时触发提示。
var isDirty = function(){return false; }
$ b $ window.onload = function(){
window.addEventListener(beforeunload,function(e){
if(formSubmitting ||!isDirty()){
return undefined;
}
var confirmationMessage ='看起来您正在编辑某些内容'
+'如果您在保存之前离开,您的更改将会丢失';
(e || window.event).returnValue = confirmationMessage; // Gecko + IE
return confirmationMessage; // Gecko + Webkit,Safari,Chrome等
});
};
现在执行 isDirty
方法,是各种方法。
您可以使用,但这种方法有一些缺陷。首先,你必须修改代码以使用任何形式( $(form)。each()
会做),但最大的问题是jQuery的 serialize()
仅适用于已命名的非禁用元素,因此更改任何禁用或未命名的元素都不会触发脏标志。 ,就像使控件只读,而不是启用,序列化,然后再次禁用控件。
因此,事件看起来是一种方式。您可以尝试。此事件有几个问题:
也,因此也不适用于虚拟输入。
,并且与上述所有事件处理解决方案一样,不支持撤消。当用户改变一个文本框然后撤消它,或者检查并取消选中一个复选框时,表单仍然被认为是脏的。
当你想要实现更多的行为,比如忽略某些元素,你会做更多的工作。
不要重新发明轮子:
因此,在您考虑实施这些解决方案和所有必需的解决方法之前,意识到您正在重新发明轮子,并且您很容易遇到其他人已经为您解决的问题。
如果您的应用程序已经使用jQuery,那么您最好使用经过测试的代码,而不是自己编写代码,并使用第三方库来完成所有这些。 效果很好,请参阅他们的。这很简单:
< script src =jquery.are-you-sure.js>< /脚本>
< script>
$(function(){
$('#myForm')。areYouSure(
{
message:'看起来您已经在编辑内容了。'
+'如果您在保存之前离开,您的更改将会丢失。'
}
);
});
< / script>
无处不支持的自定义消息
请注意,自2011年以来,,Firefox 4不支持此对话框中的自定义消息。截至上个月,Chrome 51正在推出。
这个网站的其他地方有一些替代方案,但我认为这样的对话已经足够清楚了:
I have some pages with forms in my application.
How can I secure the form in such a way that if someone navigates away or closes the browser tab, they should be prompted to to confirm they really want to leave the form with unsaved data?
Short, wrong answer:
You can do this by handling the beforeunload
event and returning a non-null string:
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.
});
The problem with this approach is that submitting a form is also firing the unload event. This is fixed easily by adding the a flag that you're submitting a form:
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.
});
};
Then calling the setter when submitting:
<form method="post" onsubmit="setFormSubmitting()">
<input type="submit" />
</form>
But read on...
Long, correct answer:
You also don't want to show this message when the user hasn't changed anything on your forms. One solution is to use the beforeunload
event in combination with a "dirty" flag, which only triggers the prompt if it's really relevant.
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.
});
};
Now to implement the isDirty
method, there are various approaches.
You can use jQuery and form serialization, but this approach has some flaws. First you have to alter the code to work on any form ($("form").each()
will do), but the greatest problem is that jQuery's serialize()
will only work on named, non-disabled elements, so changing any disabled or unnamed element will not trigger the dirty flag. There are workarounds for that, like making controls readonly instead of enabling, serializing and then disabling the controls again.
So events seem the way to go. You can try listening for keypresses. This event has a few issues:
- Won't trigger on checkboxes, radio buttons, or other elements that are being altered through mouse input.
- Will trigger for irrelevant keypresses like the key.
- Won't trigger on values set through JavaScript code.
- Won't trigger on cutting or pasting text through context menus.
- Won't work for virtual inputs like datepickers or checkbox/radiobutton beautifiers which save their value in a hidden input through JavaScript.
The change
event also doesn't trigger on values set from JavaScript code, so also won't work for virtual inputs.
Binding the input
event to all input
s (and textarea
s and select
s) on your page won't work on older browsers and, like all event handling solutions mentioned above, doesn't support undo. When a user changes a textbox and then undoes that, or checks and unchecks a checkbox, the form is still considered dirty.
And when you want to implement more behavior, like ignoring certain elements, you'll have even more work to do.
Don't reinvent the wheel:
So before you think about implementing those solutions and all required workarounds, realize you're reinventing the wheel and you're prone to running into problems others have already solved for you.
If your application already uses jQuery, you may as well use tested, maintained code instead of rolling your own, and use a third-part library for all of this. jQuery's Are You Sure? plugin works great, see their demo page. It's as simple as this:
<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>
Custom messages not supported everywhere
Do note that since 2011 already, Firefox 4 didn't support custom messages in this dialog. As of last month, Chrome 51 is being rolled out in which custom messages are also being removed.
Some alternatives exist elsewhere on this site, but I think a dialog like this is clear enough:
这篇关于在离开未保存更改的网页前警告用户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!