38

我正在使用 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

4 回答 4

38

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

 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;
     });
});
于 2012-08-01T20:03:33.647 回答
17

您可以使用 .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');
    });
}
于 2014-08-26T17:04:20.183 回答
11

您可以处理submit()事件,该事件仅在您的表单提交时发生。

在该事件中,将您的标志变量设置formHasChanged为 false 以允许继续卸载。此外,这只是一个建议,但由于该标志变量的用途已经改变,因此您可能希望将其重命名为“warnBeforeUnload”

$(document).submit(function(){
    warnBeforeUnload = false;
});
于 2012-08-01T20:01:50.630 回答
3

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

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

  1. 表格的isDirty处理:

    $('form.pleaseSave').on('change', function() {
      $(this).addClass('isDirty');
    });
    
  2. “你确定吗?” 对话逻辑:

    $(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类的表单。卸载页面的所有其他原因然后召唤我们的“你确定吗?” 对话。

PS 我在这里使用 jQuery,但我认为该.target.activeElement属性也可以在纯 JavaScript 中使用。

于 2015-08-26T18:47:15.390 回答