我如何覆盖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事件。

405234 次浏览

你不能修改onbeforeunload的默认对话框,所以最好的办法可能是使用它。

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

这是参考资料 to this from Microsoft:

当一个字符串被赋值给window的returnValue属性时。事件时,将出现一个对话框,让用户选择是否停留在当前页面并保留分配给它的字符串。对话框中出现的默认语句,“您确定要导航离开此页吗?”... 按“确定”继续,或按“取消”保持在当前页面。”,不能删除或更改。

问题似乎是:

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

结果是,似乎没有办法将false分配给onbeforeunload来防止它出现默认对话框。

jQuery的附加说明:

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

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

Edit 09/04/2018: custom messages in onbeforeunload dialogs are deprecated since chrome-51 (cf: release note)

使用专用版本的“绑定”命令“一”。事件处理程序第一次执行后,将自动将其作为事件处理程序删除。

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

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

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

重要的是,如果不需要提示,不要返回任何东西,因为IE和其他浏览器的行为在这里是不同的。

我也遇到了同样的问题,我可以用我的消息获得自己的对话框,但我面临的问题是: 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;

您可以检测到用户按下了哪个按钮(ok或cancel),因为onunload函数仅在用户选择离开页面时调用。尽管在这个函数中可能性是有限的,因为DOM正在被折叠。你可以运行javascript,但ajax POST不做任何事情,因此你不能使用这种方法自动注销。但是有一个解决方案。window.open('logout.php')在onunload函数中执行,因此用户将注销并打开一个新窗口。

function onunload = (){
window.open('logout.php');
}
此代码在用户离开页面或关闭活动窗口时调用,用户通过'logout.php'退出。 当注销php时,新窗口将立即关闭,代码如下:

window.close();
 <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

虽然在某些情况下对该方框无能为力,但您可以拦截点击链接的人。对我来说,这对于大多数情况来说都是值得的,作为备用方案,我留下了unload事件。

我已经使用了Boxy而不是标准的jQuery对话框,它可以在这里: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.';
}
};

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

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

1)使用onbeforeunload,而不是onunload。

2)重要的是避免执行return语句。我这么说不是为了避免从你的联络人那里回来。你可以返回,但你要确保你到达了函数的结尾,并且不执行return语句。在这些条件下,不会出现内置的标准对话框。

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

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

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

这不能在chrome现在做,以避免垃圾邮件,参考Javascript onbeforeunload不显示自定义消息了解更多细节。

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分钟内删除了对自定义消息的支持

试试这个

$(window).bind('beforeunload', function (event) {
setTimeout(function () {
var retVal = confirm("Do you want to continue ?");
if (retVal == true) {
alert("User wants to continue!");
return true;
}
else {
window.stop();
return false;
}
});
return;
});