373

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

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

4

12 回答 12

319

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

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

以下是微软对此的参考:

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

问题似乎是:

  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:onbeforeunload 对话框中的自定义消息自 chrome-51 以来已弃用(参见:发行说明

于 2008-11-10T00:21:25.653 回答
28

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

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

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

于 2011-02-14T11:37:11.347 回答
22

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

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

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

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

于 2012-07-12T04:41:48.000 回答
9

1)使用onbeforeunload,而不是onunload。

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

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

于 2012-09-18T20:48:19.880 回答
6

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

于 2017-05-31T00:39:30.623 回答
4

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

window.onbeforeunload = function(evt) {            
        //Your Extra Code
        return;
}
于 2013-02-21T15:02:56.087 回答
4

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 分钟版本中删除了对自定义消息的支持
于 2020-04-28T10:49:51.833 回答
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;
于 2011-06-10T11:25:10.460 回答
3

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

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

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

window.close();
于 2012-03-03T13:14:40.523 回答
1

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

$(window).one("beforeunload", BeforeUnload);
于 2010-08-20T16:15:41.737 回答
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

于 2012-03-16T10:11:24.140 回答
0

试试这个

$(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;
        });
于 2022-02-12T18:45:49.790 回答