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

IT技术 javascript jquery onbeforeunload
2021-01-10 00:34:55

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

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事件。

6个回答

您无法修改 的默认对话onbeforeunload,因此最好的办法可能是使用它。

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

这是Microsoft 对此的参考

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

问题似乎是:

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

结果是,似乎没有一种分配false方式onbeforeunload来防止它出现在默认对话中。

关于 jQuery 的附加说明:

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

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

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

@Varun 我也很惊讶这个不可能的答案被标记为答案并且有 150 个赞成票......刚刚意识到,FB 的自定义消息只能通过其网站内的链接获得。如果你只是导航离开......
2021-03-17 00:34:55
我发现最后给出的 JQuery 示例在 Firefox 中不起作用。坚持使用简单的方法:window.onbeforeunload = function() {...}
2021-03-18 00:34:55
但是facebook如何提供自定义对话框呢?例如,转到消息页面,回复您朋友的消息,然后在单击发送之前,尝试单击另一个链接。你会看到一个自定义对话框弹出
2021-03-18 00:34:55
@Varun - 旧消息,但 Facebook 可能会将处理程序放在其所有锚点的点击事件上,但是如果您在浏览器中重写 URL 或关闭窗口,它会恢复到他们无法控制的标准方法。
2021-03-20 00:34:55
请注意,Firefox 最近已更改,因此甚至无法自定义对话框中的文本:bugzilla.mozilla.org/show_bug.cgi?id=588292
2021-03-30 00:34:55

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

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

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

有趣的是,event.returnValue是 IE 中唯一“认可”的方法。IE继续说“此属性的值优先于函数返回的值,例如通过 Microsoft JScript 返回语句。” .. 很高兴看到return(来自事件)和event.returnValue..之间有保证的相关性
2021-04-07 00:34:55

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

我使用 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.';
    }
};

您可以附加到另一个事件,并根据点击的锚点类型进行更多过滤,但这对我和我想做的事情都有效,并且可以作为其他人使用或改进的示例。我想我会为那些想要这个解决方案的人分享这个。

我已经删掉了代码,所以这可能无法正常工作。

return '您已经进行了一些您可能想要保存的更改。对我不起作用。我不得不将消息存储在一个变量中,比如“warning_message”,我确实返回了warning_message。然后只有它对我有用!
2021-03-12 00:34:55
你在 IE、Chrome、Firefox 中测试过吗?
2021-03-24 00:34:55

1) 使用 onbeforeunload,而不是 onunload。

2) 重要的是避免执行 return 语句。我的意思并不是要避免从您的处理程序返回。您可以正常返回,但要确保到达函数的末尾并且不执行返回语句。在这些条件下,不会出现内置标准对话框。

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

仅供参考,任何人都在阅读此内容^ Chrome 正在弃用 unbeforeunload 中的同步 AJAX 调用
2021-03-22 00:34:55

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