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

fle*_*esh 341 javascript jquery onbeforeunload

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

window.onbeforeunload=handler
Run Code Online (Sandbox Code Playgroud)

这有效,但它会引发一个默认对话框,其中包含一条包含我自己文本的令人生气的标准消息.我需要完全替换标准消息,所以我的文本是清楚的,或者(更好)用一个模式对话框替换整个对话框使用jQuery.

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

我的页面中的Javascript:

<script type="text/javascript">   
   window.onbeforeunload=closeIt;
</script>
Run Code Online (Sandbox Code Playgroud)

closeIt()函数:

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

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

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

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

Owe*_*wen 295

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

window.onbeforeunload = function() {
    return 'You have unsaved changes!';
}
Run Code Online (Sandbox Code Playgroud)

以下是 Microsoft对此的引用:

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

问题似乎是:

  1. onbeforeunload被调用时,它会采取的处理程序的返回值window.event.returnValue.
  2. 然后它将返回值解析为字符串(除非它为null).
  3. 由于false被解析为字符串,因此将触发对话框,然后将传递适当的true/ false.

结果是,似乎没有一种分配false方法onbeforeunload来阻止它进入默认对话.

关于jQuery的附加说明:

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

    $(window).bind('beforeunload', function() {} );
    
    Run Code Online (Sandbox Code Playgroud)

编辑09/04/2018:自chrome-51以来,不推荐使用onbeforeunload对话框中的自定义消息(参见:发行说明)

  • 只是注意到Firefox最近被更改,因此对话框中的文本甚至无法自定义:https://bugzilla.mozilla.org/show_bug.cgi?id = 582892 (21认同)
  • 我发现最后给出的JQuery示例不适用于firefox.坚持用简单的方法:window.onbeforeunload = function(){...} (20认同)
  • @Varun - 旧的新闻,但Facebook可能会把处理程序放在所有锚点的click事件上,但是如果你在浏览器中重写URL或关闭窗口,它将恢复到他们无法控制的标准方法. (19认同)
  • 但是facebook如何提供自定义对话框呢?例如,转到消息页面,回复朋友的消息,然后在单击发送之前,尝试单击另一个链接.你会看到一个自定义对话框弹出窗口 (15认同)

小智 28

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

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

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


Dan*_*wer 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.';
    }
};
Run Code Online (Sandbox Code Playgroud)

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

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


use*_*763 9

1)使用onbeforeunload,而不是onunload.

2)重要的是避免执行return语句.这并不意味着避免从你的处理程序返回.你可以返回,但你可以通过确保到达函数的末尾并且不执行return语句来实现.在这些条件下,不会发生内置标准对话框.

3)如果你使用onbeforeunload,你可以在你的unbeforeunload处理程序中运行ajax调用来整理服务器,但它必须是同步的,你必须等待并处理onbeforeunload处理程序中的回复(仍然尊重上述条件(2).我这样做,它工作正常.如果你进行同步ajax调用,一切都会被阻止,直到响应回来.如果您执行异步操作,认为您不关心来自服务器的回复,则页面卸载将继续,并且此过程将中止您的ajax调用 - 包括远程脚本(如果它正在运行).


小智 8

角度 9 方法:

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

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

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


Abh*_*eet 5

为了避免垃圾邮件,现在无法在 chrome 中完成此操作,请参阅javascript onbeforeunload 不显示自定义消息以了解更多详细信息。