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

时间:2009-11-26 00:50:45

标签: javascript firefox onbeforeunload

我正在创建一个安装了beforeunload处理程序的弹出窗口。当使用“关闭”文件菜单项关闭弹出窗口时,会先调用beforeunload处理程序两次,从而产生两个“你确定要关闭此窗口吗?”消息出现。

这是Firefox的一个错误,我reported it here,但我仍然希望有办法防止这种情况发生。你能想到一个理智的方法来检测双重前载以防止双重消息问题吗?问题是Firefox没有告诉我用户选择点击的对话框中的哪个按钮 - 确定或取消。

9 个答案:

答案 0 :(得分:2)

<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>

答案 1 :(得分:1)

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

答案 2 :(得分:1)

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

报告了这个问题

答案 3 :(得分:1)

我发现的最佳解决方案是使用一个标志全局变量,该变量在经过这么多毫秒后重置,比如说500(这样可以确保可以再次调用该函数,但不能立即调用它)。

参见最后一段代码:

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

答案 4 :(得分:1)

我在Chrome 21,Firefox 14,IE 7-9,Safari 5(在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();

答案 5 :(得分:0)

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

答案 6 :(得分:0)

我使用以下代码段来跟踪exitcount

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

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

并在Window unload事件中

$(window).bind("beforeunload", function(){


            if (MTG.exitCount<=0) 
            {

                             //do your thing, save etc
            }   
            MTG.exitCount++;




});

答案 7 :(得分:0)

我发现不是自己调用confirm(),而是执行even.preventDefault();在beforeunload事件中。 Firefox引发了自己的确认对话框。 我不确定这是否是正确/标准的事情,但这就是他们这样做的方式。

答案 8 :(得分:-1)

我有一个文档用window.open打开另一个弹出窗口。在原始窗口中,我已经注册了(使用jquery)一个用于&#34;卸载&#34;像这样的事件:

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

我遇到过这个页面,因为该事件有效地触发了两次。我发现它不是一个bug,它会触发两次,因为它会触发一次&#34; about:blank&#34;页面被您的页面替换,另一页面被卸载。

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

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

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