【问题标题】:Activating OnBeforeUnload ONLY when field values have changed仅在字段值更改时激活 OnBeforeUnload
【发布时间】:2010-10-29 20:01:14
【问题描述】:

我想要实现的是警告用户未保存的更改,如果他/她试图关闭页面或导航离开它而不先保存。

我已经设法让OnBeforeUnload() 对话框弹出...但是如果用户没有修改任何字段值,我根本不希望它显示。为此,我使用了这个名为 is_modified 的隐藏输入字段,它以默认值 false 开头,当任何字段为编辑。

我尝试将 change 事件绑定到此 is_modified 字段以尝试检测值更改...然后才激活 OnBeforeUnload。

$( '#is_modified' ).change( function() {
    if( $( '#is_modified' ).val() == 'true' )
        window.onbeforeunload = function() { return "You have unsaved changes."; }
});

但据我所知,change() 事件仅在这 3 个步骤之后才起作用 - 字段接收焦点,更改值并且字段失去焦点。在隐藏输入字段的情况下,我不确定这个接收和失去焦点部分是如何工作的!因此,onbeforeunload 函数永远不会被激活。

谁能建议一种方法来维护 is_modified 的触发器?

谢谢。

【问题讨论】:

    标签: javascript dialog conditional triggers onbeforeunload


    【解决方案1】:

    我也有类似的需求,所以想出了下面的 jQuery 脚本:

    $(document).ready(function() {
        needToConfirm = false; 
        window.onbeforeunload = askConfirm;
    });
    
    function askConfirm() {
        if (needToConfirm) {
            // Put your custom message here 
            return "Your unsaved data will be lost."; 
        }
    }
    
    $("select,input,textarea").change(function() {
        needToConfirm = true;
    });
    

    上面的代码检查needToConfirm变量,如果是true,那么它会显示警告信息。 每当inputselecttextarea 元素值发生更改时,needToConfirm 变量就会设置为true


    PS: Firefox > 4 不允许为 onbeforeunload 自定义消息。
    参考:https://bugzilla.mozilla.org/show_bug.cgi?id=588292


    更新:如果您是性能狂,您会喜欢@KyleMit's 的建议。 他编写了一个 jQuery 扩展 only(),它只会对任何元素执行一次。

    $.fn.only = function (events, callback) {
        //The handler is executed at most once for all elements for all event types.
        var $this = $(this).on(events, myCallback);
        function myCallback(e) {
            $this.off(events, myCallback);
            callback.call(this, e);
        }
        return this
    };    
    
    $(":input").only('change', function() {
        needToConfirm = true;
    });
    

    【讨论】:

    • 它就像一个魅力。但是有一个小问题:我无法更改消息。我想写下我自己的信息,比如:“你疯了,想离开吗?”但我无法让它工作......
    • 感谢您的回答,但我发现问题是另一个问题。我正在使用 Firefox,并且有一个功能不允许更改此消息。我在 chrome 中尝试了它,它可以工作,但它不会在 firefox 中工作......
    • @marianobianchi 是的,在 FIrefox 4 之后,onbeforeunload 不允许使用自定义消息@bugzilla.mozilla.org/show_bug.cgi?id=588292。将相应地更新我的答案
    • 几个建议:您可以使用 jQuery 的 ":input" selector 来简化更改选择器。此外,在第一个事件将 needToConfirm 设置为 true 后,您无需继续侦听和触发更改事件。 .change() 只是 .on('change') 的简写。您可以使用.one('change') 而不是on,这样事件就不需要继续触发以进行后续更改。
    • 当我们这样做的时候,如果你愿意添加扩展方法,我写了一个名为.only() 的 5 行扩展方法,它只会在任何调用它时触发一次元素。而one每个元素 每个事件类型最多执行一次。”它的代码多一点,但更方便、更简洁,而且处理的工作量更少。如果您有一个包含许多不同字段的表单,并且会不断触发,那么它可能会有所帮助。 Here's a demo in fiddle
    【解决方案2】:

    我们只是使用Window.onbeforeunload 作为我们的“更改”标志。这是我们正在做的事情,(使用lowpro):

    Event.addBehavior({
      "input[type=radio]:change,input[type=text]:change,input[type=checkbox]:change,select:change": function(ev) {
           window.onbeforeunload = confirmLeave;
      }
      ".button.submit-button:click": function(ev) {
           window.onbeforeunload = null;
      },
    });
    
    
    function confirmLeave(){
        return "Changes to this form have not been saved. If you leave, your changes will be lost."  
    }
    

    【讨论】:

    • 显然在 IE 中设置 onbeforeunload=null 失败:bustedmug.blogspot.com/2007/01/…
    • 这似乎是一个仅限 IE7 的错误——它在 IE8 中运行良好,这是我所必须支持的,幸运的是!
    【解决方案3】:

    以下在 jQuery 中运行良好:

    var needToConfirm = false;
    
    $("input,textarea").on("input", function() {
      needToConfirm = true;
    });
    
    $("select").change(function() {
      needToConfirm = true;
    });
    
    window.onbeforeunload = function(){        
      if(needToConfirm) {
        return "If you exit this page, your unsaved changes will be lost.";        
      }
    }   
    

    如果用户提交表单以保存更改,您可能需要添加此内容(将 #mainForm 更改为他们提交的表单的 ID):

    $("#mainForm").submit(function() {
      needToConfirm = false;
    });
    

    【讨论】:

    • 这段代码对我有用,我只是改变了最后一部分,所以我不需要写 #mainForm `//Form Submit 以不显示警告 jQuery(document).on("submit" , "form", function (event) { // 禁用警告 needToConfirm = false; });`
    【解决方案4】:
    $(window).bind('beforeunload',function() {
     return "'Are you sure you want to leave the page. All data will be lost!";
    });
    
    $('#a_exit').live('click',function() {
        $(window).unbind('beforeunload');
    });
    

    以上对我有用。

    【讨论】:

      【解决方案5】:

      以不同的方式尝试您的逻辑。意思是,将检查输入字段值的逻辑放在onbeforeunload 方法中。

      window.onbeforeunload = function () { 
          if ($("#is_modified").val() == 'true') { 
              return "You have unsaved changes."; 
          } else { 
              return true; // I think true is the proper value here 
          } 
      };
      

      【讨论】:

      • "true" 不是正确的值。在某些浏览器中(至少是 Firefox,也许更多)返回“null”将取消对话框。但是,在 IE 中,我找不到从处理程序中取消对话框的方法。唯一对我有用的是完全事先删除处理程序(即“window.beforeunload = null”),就像 Bryan Larsen 的回答一样。
      • 很公平。可悲的是,在我回答之前,我没有彻底测试我的解决方案。 :(
      • 我知道我参加聚会有点晚了,但我只是碰到了这个。但是在 IE 中,如果函数返回 undefined(或不返回任何内容),则不会显示对话框(这也适用于 FF)。我尝试返回 true/false/null,而 IE 只会将“true”/“false”/“null”作为对话框中的文本。不知道为什么。希望这对其他人有帮助。
      • 我确认@JonathanKuhn 对 Safari 8.0.7 发表评论
      【解决方案6】:

      在 IE9 中你可以使用简单的返回语句 (re),它不会显示任何对话框。快乐编码..

      【讨论】:

        【解决方案7】:

        为什么不让onbeforeunload 调用一个函数来检查值是否已更改,如果更改则返回“未保存的更改”确认?

        【讨论】:

          猜你喜欢
          • 2020-04-26
          • 1970-01-01
          • 2020-05-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-09-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多