window.onbeforeunload – 仅在不提交表单时显示警告
我正在使用window.onbeforeunload来防止用户在更改表单上的值后导航。 这工作正常,除了它还显示用户提交表单时的警告(不需要)。
如何在表单提交时不显示警告的情况下执行此操作?
当前代码:
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; } } });
使用表单的提交事件来设置标志可能对您有用。
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; }); });
您可以使用.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'); }); }
您可以处理submit()事件,该事件仅适用于您的表单提交。
在该事件中,将标志变量formHasChanged
设置为false以允许卸载继续。 另外,只是一个建议,但由于该标志变量的目的将发生变化,因此您可能希望将其重命名为’warnBeforeUnload’
$(document).submit(function(){ warnBeforeUnload = false; });
我一直在寻找更好的解决方案。 我们想要的只是将一个或多个触发器排除在创建“你确定吗?”之外。 对话框。 因此,我们不应该为越来越多的副作用创建越来越多的变通方法。 如果在没有提交按钮的click
事件的情况下提交表单怎么办? 如果我们的点击处理程序删除了isDirty
状态但之后表单提交被阻止了怎么办? 当然我们可以改变触发器的行为,但正确的位置是处理对话框的逻辑。 绑定到表单的submit
事件而不是绑定到提交按钮的click
事件是这个线程中的答案优于我之前看到的其他一些,但这个恕我直言只是修复了错误的方法。
在挖掘onbeforeunload
事件的事件对象后,我找到了.target.activeElement
属性,该属性包含最初触发事件的元素。 所以,是的,它是按钮或链接或我们点击的任何内容(或者根本没有,如果浏览器本身导航了)。 我们“你确定吗?” 然后,对话逻辑将自身缩减为以下两个组件:
-
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 });
就是这样。 无需解决方法。 只需给出触发器(提交和其他操作按钮)一个ignorePleaseSave
类和我们想要将对话框应用于pleaseSave
类的pleaseSave
。 卸载页面的所有其他原因然后召唤我们“你确定吗?” 对话。
PS我在这里使用jQuery,但我认为.target.activeElement
属性也可以在纯JavaScript中使用。