代码之家  ›  专栏  ›  技术社区  ›  Zarkonnen

window.beforeunload在firefox中调用了两次-如何解决这个问题?

  •  5
  • Zarkonnen  · 技术社区  · 16 年前

    我正在创建一个安装了beforeunload处理程序的弹出窗口。当使用“关闭”文件菜单项关闭弹出窗口时,将调用两次BeforeUnload处理程序,结果是两次“是否确实要关闭此窗口?”出现消息。

    这是一个关于火狐的bug,我已经 reported it here 但我仍然希望有一种方法来防止这种情况的发生。您能想出一种在卸载前检测双邮件的明智方法来防止双邮件问题吗?问题是,火狐没有告诉我用户选择点击对话框中的哪个按钮-确定或取消。

    9 回复  |  直到 10 年前
        1
  •  2
  •   Donut    15 年前
    <script type="text/javascript">
    var onBeforeUnloadFired = false;
    
    window.onbeforeunload = function ()
    {
        if (!onBeforeUnloadFired) {
            onBeforeUnloadFired = true;
            event.returnValue = "You have attempted to leave this page.  If you have made any changes to the fields without clicking the Save button, your changes will be lost.  Are you sure you want to exit this page?";
       }
    
       window.setTimeout("ResetOnBeforeUnloadFired()", 10);
    }
    
    function ResetOnBeforeUnloadFired() {
       onBeforeUnloadFired = false;
    }    
    </script>
    
        2
  •  1
  •   Mark Bessey    16 年前

    在处理程序中设置一个变量,以防止第二次出现对话框。之后使用setTimeout将其重置。

        3
  •  1
  •   Zarkonnen    16 年前

    这绝对是一个FF错误。我已经在 https://bugzilla.mozilla.org/show_bug.cgi?id=531199

        4
  •  1
  •   artur    16 年前

    我找到的最好的解决方案是使用一个标志全局变量,它在这么多毫秒(比如500毫秒)后被重置(这可以确保函数可以再次调用,但不会在出现后立即调用)。

    请参阅中的最后一个代码:

    http://social.msdn.microsoft.com/Forums/en/sharepointinfopath/thread/13000cd8-5c50-4260-a0d2-bc404764966d

        5
  •  1
  •   oldmanbim    13 年前

    我在Chrome21、火狐14、IE7-9、Safari5(在PC上)中发现了这个问题。

    以下内容适用于所有这些浏览器。如果在事件期间删除window.onbeforeunload函数,这将阻止第二次调用。如果用户决定留在页面上,技巧是重置window.onbeforeunload函数。

    var window_on_before_unload = function(e) {
        var msg;
        // Do here what you ever you need to do
        msg = "Message for user";
    
        // Prevent next "window.onbeforeunload" from re-running this code.
        // Ensure that if the user decides to stay on the page that
        // this code is run the next time the user tries to leave the page.
        window.onbeforeunload = set_on_before_unload;
    
        // Prepare message for user
        if (msg) {
            if (/irefox\/([4-9]|1\d+)/.test(navigator.userAgent))
                alert(msg
                        + '\n\nThe next dialog will allow you to stay here or continue\nSee Firefox bug #588292');
    
            (e = e || window.event).returnValue = msg;
            return msg;
        }
    };
    
    // Set window.onbeforeunload to the above handler.
    // @uses window_on_before_unload
    // @param {Event} e
    var set_on_before_unload = function(e) {
        // Initialize the handler for window.onbeforeunload.
        window.onbeforeunload = window_on_before_unload;
    }
    
    // Initialize the handler for window.onbeforeunload.
    set_on_before_unload();
    
        6
  •  0
  •   leepowers    16 年前

    在处理程序内创建设置为true的全局变量。仅当此变量为假时显示警报/弹出窗口。

        7
  •  0
  •   Nilesh    15 年前

    我使用以下代码段跟踪exitcount

    当页面加载时,初始化以下变量exitcount

    if (typeof(MTG) == 'undefined') MTG = {};
    MTG.exitCount=0; 
    

    在窗口卸载事件中

    $(window).bind("beforeunload", function(){
    
    
                if (MTG.exitCount<=0) 
                {
    
                                 //do your thing, save etc
                }   
                MTG.exitCount++;
    
    
    
    
    });
    
        8
  •  0
  •   Toby    14 年前

    我发现,不要自己调用confirm(),只需在beforeunload事件中执行event.preventDefault();即可。火狐会弹出自己的确认对话框。 我不确定这是否是正确/标准的做法,但他们就是这样做的。

        9
  •  -1
  •   Danielside    10 年前

    我有一个文档正在用window.open打开另一个弹出窗口。在最初的窗口中,我(使用jquery)注册了“卸载”事件的侦听器,如下所示:

    var popup_window = window.open(...) 
    $(popup_window).on('unload', function(event) ...
    

    我看到这个页面是因为事件实际上触发了两次。我发现它不是一个bug,它会触发两次,因为它会触发一次“about:blank”页面被您的页面替换,另一个页面被卸载。

    我要做的就是通过查询原始事件来过滤我感兴趣的事件:

    function (event) {
       var original_url = e.originalEvent.originalTarget.URL;
       if (original_url != 'about:blank')
       {
           ... do cool things ...
       }
    }
    

    我不知道这是否适用于最初的问题,因为这是打开另一个窗口的特殊情况,但我希望它有帮助。