window.onbeforeunload - 仅在不提交表单时显示警告

时间:2012-08-01 19:57:59

标签: javascript jquery 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;
        }
    }
});

4 个答案:

答案 0 :(得分:33)

使用表单的提交事件设置标志可能对您有用。

 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;
     });
});

答案 1 :(得分:15)

您可以使用.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');
    });
}

答案 2 :(得分:10)

您可以处理submit()事件,该事件仅适用于您的表单提交。

在该事件中,将标志变量formHasChanged设置为false以允许卸载继续。另外,只是一个建议,但由于该标志变量的目的将发生变化,因此您可能希望将其重命名为'warnBeforeUnload'

$(document).submit(function(){
    warnBeforeUnload = false;
});

答案 3 :(得分:2)

我一直在寻找更好的解决方案。我们想要的只是将一个或多个触发器排除在创建“你确定吗?”之外。对话框。因此,我们不应该为越来越多的副作用创建越来越多的变通方法。如果在没有提交按钮iframe事件的情况下提交表单怎么办?如果我们的点击处理程序删除了click状态但之后表单提交被阻止了怎么办?当然我们可以改变触发器的行为,但正确的位置是处理对话框的逻辑。绑定到表单的isDirty事件而不是绑定到提交按钮的submit事件是这个线程中的答案优于我之前看到的其他一些,但是这个恕我直言只是修复了错误的方法。

在对click事件的事件对象进行一些挖掘之后,我找到了onbeforeunload属性,该属性包含最初触发事件的元素。所以,是的,它是按钮或链接或我们点击的任何内容(或者根本没有,如果浏览器本身导航了)。我们“你确定吗?”然后,对话逻辑将自身缩减为以下两个组件:

  1. .target.activeElement处理表单:

    isDirty
  2. “你确定吗?”对话逻辑:

    $('form.pleaseSave').on('change', function() {
      $(this).addClass('isDirty');
    });
    
  3. 就像那样。无需解决方法。只需为触发器(提交和其他操作按钮)提供$(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类的表单。卸载页面的所有其他原因然后召唤我们“你确定吗?”对话框。

    P.S。我在这里使用jQuery,但我认为pleaseSave属性也可以在纯JavaScript中使用。