如何覆盖OnBeforeUnload对话框并将其替换为我自己的?

时间:2008-11-09 23:24:18

标签: javascript jquery onbeforeunload

我需要在用户离开页面之前警告用户未保存的更改(这是一个非常常见的问题)。

window.onbeforeunload=handler

这样可行,但它会引发一个默认对话框,其中包含一条包含我自己文本的令人恼火的标准消息。我需要完全替换标准消息,所以我的文本很清楚,或者(甚至更好)使用jQuery用模态对话框替换整个对话框。

到目前为止,我失败了,我还没有找到任何似乎有答案的人。它甚至可能吗?

我页面中的Javascript:

<script type="text/javascript">   
   window.onbeforeunload=closeIt;
</script>

closeIt()函数:

function closeIt()
{
  if (changes == "true" || files == "true")
  {
      return "Here you can append a custom message to the default dialog.";
  }
}

使用jQuery和jqModal我尝试过这种事情(使用自定义确认对话框):

$(window).beforeunload(function() {
        confirm('new message: ' + this.href + ' !', this.href);
        return false;
    });

这也行不通 - 我似乎无法绑定到beforeunload事件。

10 个答案:

答案 0 :(得分:290)

您无法修改onbeforeunload的默认对话框,因此您最好的选择是使用它。

window.onbeforeunload = function() {
    return 'You have unsaved changes!';
}
来自Microsoft的

Here's a reference

  

当一个字符串被分配给window.event的returnValue属性时,会出现一个对话框,让用户可以选择保留当前页面并保留分配给它的字符串。对话框中显示的默认语句“您确定要离开此页面吗?...按OK继续,或按取消保留在当前页面上。”,无法删除或更改。

问题似乎是:

  1. 调用onbeforeunload时,会将处理程序的返回值设为window.event.returnValue
  2. 然后它将返回值解析为字符串(除非它为null)。
  3. 由于false被解析为字符串,因此会触发对话框,然后会传递相应的true / false
  4. 结果是,似乎没有办法将false分配给onbeforeunload以防止它出现在默认对话框中。

    关于jQuery的补充说明:

    • 在jQuery中设置事件可能会有问题,因为这样也会发生其他onbeforeunload事件。如果您只希望发生卸载事件,我会坚持使用简单的“JavaScript”。
    • jQuery没有onbeforeunload的快捷方式,因此您必须使用通用bind语法。

      $(window).bind('beforeunload', function() {} );
      

    编辑09/04/2018 :自chrome-51以来,不推荐使用onbeforeunload对话框中的自定义消息(cf:release note

答案 1 :(得分:27)

使用jQuery并在IE8,Chrome和Firefox中测试过,对我有用的是:

$(window).bind("beforeunload",function(event) {
    if(hasChanged) return "You have unsaved changes";
});

如果不需要提示,则不要返回任何内容,因为IE和其他浏览器行为之间存在差异。

答案 2 :(得分:20)

虽然在某些情况下你无法对盒子做任何事情,但你可以拦截某人点击链接。对我来说,这对于大多数场景来说都是值得的,而作为后备,我已经离开了卸载事件。

我使用的是Boxy而不是标准的jQuery Dialog,可以在这里找到:http://onehackoranother.com/projects/jquery/boxy/

$(':input').change(function() {
    if(!is_dirty){
        // When the user changes a field on this page, set our is_dirty flag.
        is_dirty = true;
    }
});

$('a').mousedown(function(e) {
    if(is_dirty) {
        // if the user navigates away from this page via an anchor link, 
        //    popup a new boxy confirmation.
        answer = Boxy.confirm("You have made some changes which you might want to save.");
    }
});

window.onbeforeunload = function() {
if((is_dirty)&&(!answer)){
            // call this if the box wasn't shown.
    return 'You have made some changes which you might want to save.';
    }
};

你可以附加到另一个事件,并过滤更多关于点击了什么类型的锚点,但这对我和我想做的事情有用,并作为其他人使用或改进的例子。我想我会为那些想要这个解决方案的人分享这个。

我已经删除了代码,因此可能无法正常工作。

答案 3 :(得分:4)

尝试放置return;而不是消息..这对我来说适用于大多数浏览器。 (这只会真正阻止对话框的呈现)

window.onbeforeunload = function(evt) {            
        //Your Extra Code
        return;
}

答案 4 :(得分:3)

我遇到了同样的问题,我可以通过我的消息获得自己的对话框,但我遇到的问题是: 1)它只是为了关闭点击而在所有导航上发出消息。 2)如果用户选择取消,我自己的确认消息仍显示浏览器的默认对话框。

以下是我找到的解决方案代码,我在母版页上写道。

function closeMe(evt) {
    if (typeof evt == 'undefined') {
        evt = window.event; }
    if (evt && evt.clientX >= (window.event.screenX - 150) &&
        evt.clientY >= -150 && evt.clientY <= 0) {
        return "Do you want to log out of your current session?";
    }
}
window.onbeforeunload = closeMe;

答案 5 :(得分:3)

您可以检测用户按下的按钮(确定或取消),因为只有当用户选择离开页面时才会调用onunload函数。在这个功能中,可能性是有限的,因为DOM正在崩溃。你可以运行javascript,但是ajax POST没有做任何事情,因此你不能使用这个方法来自动注销。但是有一个解决方案。 window.open('logout.php')在onunload函数中执行,因此用户将以新窗口打开注销。

function onunload = (){
    window.open('logout.php');
}

当用户离开页面或关闭活动窗口并且用户通过'logout.php'注销时,会调用此代码。 当注销php由代码组成时,新窗口立即关闭:

window.close();

答案 6 :(得分:3)

现在无法在Chrome中完成此操作以避免发送垃圾邮件,有关详细信息,请参阅javascript onbeforeunload not showing custom message

答案 7 :(得分:1)

如何使用“bind”命令“one”的专用版本。一旦事件处理程序第一次执行,它就会自动作为事件处理程序删除。

$(window).one("beforeunload", BeforeUnload);

答案 8 :(得分:1)

 <script type="text/javascript">
        window.onbeforeunload = function(evt) {
            var message = 'Are you sure you want to leave?';
            if (typeof evt == 'undefined') {
                evt = window.event;
            }       
            if (evt) {
                evt.returnValue = message;
            }
            return message;
        } 
    </script>

参考http://www.codeprojectdownload.com

答案 9 :(得分:1)

Angular 9方法:

constructor() {
    window.addEventListener('beforeunload', (event: BeforeUnloadEvent) => {
     if (this.generatedBarcodeIndex) {
      event.preventDefault(); // for Firefox
      event.returnValue = ''; // for Chrome
      return '';
     }
     return false;
    });
   }

浏览器支持和自定义消息的删除:

  • Chrome在51分钟内删除了对自定义消息的支持
  • Opera在38分钟内删除了对自定义消息的支持
  • Firefox在44.0分钟后删除了对自定义消息的支持
  • Safari在9.1分钟后删除了对自定义消息的支持