【问题标题】:window.onbeforeunload - Only show warning when not submitting form [duplicate]window.onbeforeunload - 仅在不提交表单时显示警告[重复]
【发布时间】:2012-08-01 19:57:59
【问题描述】:

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

【问题讨论】:

    标签: javascript jquery onbeforeunload


    【解决方案1】:

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

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

    【讨论】:

    • 我通过@Derek 接受了这个,因为我已经有自定义提交代码并且需要分别检查这两个值。
    • 在此之前我使用了 1 个变量,但它有时工作有时不工作。您的解决方案适用于 2 个变量。谢谢
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        【解决方案4】:

        我一直在寻找更好的解决方案。我们想要的只是从创建我们的“您确定吗?”中排除一个或多个触发器。对话框。所以我们不应该为越来越多的副作用创造越来越多的变通方法。如果提交表单时没有提交按钮的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 类的表单。卸载页面的所有其他原因然后召唤我们的“你确定吗?”对话框。

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

        【讨论】:

        • 这似乎是特定于浏览器的。在 Chrome 中运行良好,但在 Firefox 中的目标始终是 body
        • 刚刚在 Firefox 40 中测试过,event.target.activeElement 实际上提供了时钟元素,就像在 Chrome 中一样。我的解决方案对我来说在两种浏览器中都运行良好。
        • 我喜欢这种方法,但我无法让它在 IE 中工作。但是完全忽略事件并使用 document.activeElement 对我有用(目前仅在 Chrome 和 IE 中测试过)
        猜你喜欢
        • 2019-07-16
        • 2014-04-13
        • 2021-06-02
        • 1970-01-01
        • 2013-12-20
        • 1970-01-01
        • 1970-01-01
        • 2015-01-06
        • 1970-01-01
        相关资源
        最近更新 更多