Javascript window.onbeforeunload - 不提交表单时只显示警告
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11766658/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
window.onbeforeunload - Only show warning when not submitting form
提问by mtmurdock
I am using window.onbeforeunload to prevent the user from navigating away after changing values on a form. This is working fine, except it also shows the warning when the user submits the form (not desired).
我正在使用 window.onbeforeunload 来防止用户在更改表单上的值后导航离开。这工作正常,除了在用户提交表单(不需要)时还会显示警告。
How can I do this without showing the warning when the form submits?
当表单提交时,我该如何做到这一点而不显示警告?
Current code:
当前代码:
var formHasChanged = false;
$(document).on('change', 'form.confirm-navigation-form input, form.confirm-navigation-form select, form.confirm-navigation-form textarea', function (e) {
formHasChanged = true;
});
$(document).ready(function () {
window.onbeforeunload = function (e) {
if (formHasChanged) {
var message = "You have not saved your changes.", e = e || window.event;
if (e) {
e.returnValue = message;
}
return message;
}
}
});
回答by Jay Tomten
Using the form's submit event to set a flag might work for you.
使用表单的提交事件来设置标志可能对您有用。
var formHasChanged = false;
var submitted = false;
$(document).on('change', 'form.confirm-navigation-form input, form.confirm-navigation-form select, form.confirm-navigation-form textarea', function (e) {
formHasChanged = true;
});
$(document).ready(function () {
window.onbeforeunload = function (e) {
if (formHasChanged && !submitted) {
var message = "You have not saved your changes.", e = e || window.event;
if (e) {
e.returnValue = message;
}
return message;
}
}
$("form").submit(function() {
submitted = true;
});
});
回答by Brent White
you could use .on() to bind onbeforeunload and then use .off() to unbind it in form submission
您可以使用 .on() 绑定 onbeforeunload 然后使用 .off() 在表单提交中取消绑定
$(document).ready(function () {
// Warning
$(window).on('beforeunload', function(){
return "Any changes will be lost";
});
// Form Submit
$(document).on("submit", "form", function(event){
// disable warning
$(window).off('beforeunload');
});
}
回答by Derek Hunziker
You can handle the submit()event, which will occur only for your form submission.
您可以处理submit()事件,该事件只会在您提交表单时发生。
Within that event, set your flag variable formHasChanged
to false to allow the unload to proceed. Also, just a suggestion, but since the purpose of that flag variable will have changed, so you may want to rename it something like 'warnBeforeUnload'
在该事件中,将标志变量设置formHasChanged
为 false 以允许卸载继续。另外,只是一个建议,但由于该标志变量的用途将发生变化,因此您可能需要将其重命名为“warnBeforeUnload”
$(document).submit(function(){
warnBeforeUnload = false;
});
回答by spackmat
I was looking for a better solution to this. What we want is simply exclude one or more triggers from creating our "Are you sure?" dialog box. So we shouldn't create more and more workarounds for more and more side effects. What if the form is submitted without a click
event of the submit button? What if our click-handler removes the isDirty
status but then the form-submit is otherwise blocked afterwards? Sure we can change the behaviour of our triggers, but the right place would be the logic handling the dialog. Binding to the form's submit
event instead of binding to the submit button's click
event is an advantage of the answers in this thread above some others i saw before, but this IMHO just fixes the wrong approach.
我正在寻找更好的解决方案。我们想要的是简单地从创建我们的“你确定吗?”中排除一个或多个触发器。对话框。所以我们不应该为越来越多的副作用创造越来越多的变通方法。如果表单在没有click
提交按钮事件的情况下提交怎么办?如果我们的点击处理程序删除了isDirty
状态,但随后表单提交被阻止了怎么办?当然我们可以改变触发器的行为,但正确的地方是处理对话框的逻辑。绑定到表单的submit
事件而不是绑定到提交按钮的click
事件是这个线程中答案的一个优势,高于我之前看到的其他一些,但是这个恕我直言只是修复了错误的方法。
After some digging in the event object of the onbeforeunload
event I found the .target.activeElement
property, which holds the element, which triggered the event originally. So, yay, it is the button or link or whatever we clicked (or nothing at all, if the browser itself navigated away). Our "Are you sure?" dialog logic then reduces itself to the following two components:
在对事件的事件对象进行了一些挖掘之后,onbeforeunload
我找到了.target.activeElement
属性,该属性保存了最初触发事件的元素。所以,是的,它是按钮或链接或我们点击的任何东西(或者根本没有,如果浏览器本身导航离开)。我们的“你确定吗?” 然后对话逻辑将自身简化为以下两个组件:
The
isDirty
handling of the form:$('form.pleaseSave').on('change', function() { $(this).addClass('isDirty'); });
The "Are you sure?" dialog logic:
$(window).on('beforeunload', function(event) { // if form is dirty and trigger doesn't have a ignorePleaseSave class if ($('form.pleaseSave').hasClass('isDirty') && !$(event.target.activeElement).hasClass('ignorePleaseSave')) { return "Are you sure?" } // special hint: returning nothing doesn't summon a dialog box });
isDirty
表格的处理:$('form.pleaseSave').on('change', function() { $(this).addClass('isDirty'); });
“你确定吗?” 对话逻辑:
$(window).on('beforeunload', function(event) { // if form is dirty and trigger doesn't have a ignorePleaseSave class if ($('form.pleaseSave').hasClass('isDirty') && !$(event.target.activeElement).hasClass('ignorePleaseSave')) { return "Are you sure?" } // special hint: returning nothing doesn't summon a dialog box });
It's simply as that. No workarounds needed. Just give the triggers (submit and other action buttons) an ignorePleaseSave
class and the form we want to get the dialog applied to a pleaseSave
class. All other reasons for unloading the page then summons our "Are you sure?" dialog.
就这么简单。不需要解决方法。只需给触发器(提交和其他操作按钮)一个ignorePleaseSave
类和我们想要将对话框应用于类的表单pleaseSave
。卸载页面的所有其他原因然后召唤我们的“你确定吗?” 对话。
P.S. I am using jQuery here, but I think the .target.activeElement
property is also available in plain JavaScript.
PS 我在这里使用 jQuery,但我认为该.target.activeElement
属性也可以在纯 JavaScript 中使用。