简体   繁体   English

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

[英]How can I override the OnBeforeUnload dialog and replace it with my own?

I need to warn users about unsaved changes before they leave a page (a pretty common problem).我需要在用户离开页面之前就未保存的更改发出警告(这是一个很常见的问题)。

window.onbeforeunload = handler

This works but it raises a default dialog with an irritating standard message that wraps my own text.这有效,但它会引发一个默认对话框,其中包含一条包含我自己的文本的烦人的标准消息。 I need to either completely replace the standard message, so my text is clear, or (even better) replace the entire dialog with a modal dialog using jQuery.我需要完全替换标准消息,以便我的文本清晰,或者(甚至更好)使用 jQuery 将整个对话框替换为模态对话框。

So far I have failed and I haven't found anyone else who seems to have an answer.到目前为止,我失败了,而且我还没有找到其他人似乎有答案。 Is it even possible?有可能吗?

Javascript in my page: Javascript 在我的页面:

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

The closeIt() function: closeIt() function:

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

Using jQuery and jqModal I have tried this kind of thing (using a custom confirm dialog):使用 jQuery 和 jqModal 我已经尝试过这种事情(使用自定义确认对话框):

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

which also doesn't work - I cannot seem to bind to the beforeunload event.这也不起作用 - 我似乎无法绑定到beforeunload事件。

You can't modify the default dialogue for onbeforeunload , so your best bet may be to work with it.您无法修改onbeforeunload的默认对话,因此您最好的选择可能是使用它。

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

Here's a reference to this from Microsoft:这是微软对此的参考

When a string is assigned to the returnValue property of window.event, a dialog box appears that gives users the option to stay on the current page and retain the string that was assigned to it.当一个字符串分配给 window.event 的 returnValue 属性时,会出现一个对话框,让用户可以选择留在当前页面并保留分配给它的字符串。 The default statement that appears in the dialog box, "Are you sure you want to navigate away from this page? ... Press OK to continue, or Cancel to stay on the current page.", cannot be removed or altered.对话框中出现的默认语句“您确定要离开此页面吗?...按确定继续,或按取消留在当前页面。”,不能删除或更改。

The problem seems to be:问题似乎是:

  1. When onbeforeunload is called, it will take the return value of the handler as window.event.returnValue .onbeforeunload被调用时,它会将处理程序的返回值作为window.event.returnValue
  2. It will then parse the return value as a string (unless it is null).然后它将返回值解析为字符串(除非它为空)。
  3. Since false is parsed as a string, the dialogue box will fire, which will then pass an appropriate true / false .由于false被解析为字符串,因此将触发对话框,然后传递适当的true / false

The result is, there doesn't seem to be a way of assigning false to onbeforeunload to prevent it from the default dialogue.结果是,似乎没有办法将false分配给onbeforeunload以防止它出现在默认对话中。

Additional notes on jQuery:关于 jQuery 的附加说明:

  • Setting the event in jQuery may be problematic, as that allows other onbeforeunload events to occur as well.在 jQuery 中设置事件可能会有问题,因为这也允许其他onbeforeunload事件发生。 If you wish only for your unload event to occur I'd stick to plain ol' JavaScript for it.如果你只希望你的卸载事件发生,我会坚持使用普通的 JavaScript。
  • jQuery doesn't have a shortcut for onbeforeunload so you'd have to use the generic bind syntax. jQuery 没有onbeforeunload的快捷方式,因此您必须使用通用bind语法。

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

Edit 09/04/2018 : custom messages in onbeforeunload dialogs are deprecated since chrome-51 (cf: release note )编辑 09/04/2018 :自 chrome-51 起不推荐使用 onbeforeunload 对话框中的自定义消息(参见: 发行说明

What worked for me, using jQuery and tested in IE8, Chrome and Firefox, is:使用jQuery并在 IE8、Chrome 和 Firefox 中测试对我有用的是:

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

It is important not to return anything if no prompt is required as there are differences between IE and other browser behaviours here.如果不需要提示,请不要返回任何内容,因为 IE 和其他浏览器行为之间存在差异,这一点很重要。

While there isn't anything you can do about the box in some circumstances, you can intercept someone clicking on a link.虽然在某些情况下您无法对框做任何事情,但您可以拦截某人单击链接。 For me, this was worth the effort for most scenarios and as a fallback, I've left the unload event.对我来说,这对于大多数场景来说都是值得的,作为后备,我已经离开了卸载事件。

I've used Boxy instead of the standard jQuery Dialog, it is available here: http://onehackoranother.com/projects/jquery/boxy/我使用 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.';
    }
};

You could attach to another event, and filter more on what kind of anchor was clicked, but this works for me and what I want to do and serves as an example for others to use or improve.您可以附加到另一个事件,并根据点击的锚点类型进行更多过滤,但这对我和我想做的事情都有效,并且可以作为其他人使用或改进的示例。 Thought I would share this for those wanting this solution.我想我会为那些想要这个解决方案的人分享这个。

I have cut out code, so this may not work as is.我已经删减了代码,所以这可能无法正常工作。

1) Use onbeforeunload, not onunload. 1) 使用 onbeforeunload,而不是 onunload。

2) The important thing is to avoid executing a return statement. 2) 重要的是避免执行 return 语句。 I don't mean, by this, to avoid returning from your handler.我的意思并不是要避免从您的处理程序返回。 You return all right, but you do it by ensuring that you reach the end of the function and DO NOT execute a return statement.您可以正常返回,但是您要确保到达函数的末尾并且不执行返回语句。 Under these conditions the built-in standard dialog does not occur.在这些条件下,不会出现内置标准对话框。

3) You can, if you use onbeforeunload, run an ajax call in your unbeforeunload handler to tidy up on the server, but it must be a synchronous one, and you have to wait for and handle the reply in your onbeforeunload handler (still respecting condition (2) above). 3)你可以,如果你使用onbeforeunload,在你的unbeforeunload处理程序中运行一个ajax调用来整理服务器,但它必须是同步的,你必须在你的onbeforeunload处理程序中等待和处理回复(仍然尊重上述条件(2))。 I do this and it works fine.我这样做并且效果很好。 If you do a synchronous ajax call, everything is held up until the response comes back.如果您执行同步 ajax 调用,则一切都会暂停,直到响应返回。 If you do an asynchronous one, thinking that you don't care about the reply from the server, the page unload continues and your ajax call is aborted by this process - including a remote script if it's running.如果你做一个异步的,认为你不关心来自服务器的回复,页面卸载继续并且你的 ajax 调用被这个过程中止 - 如果它正在运行,包括一个远程脚本。

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

Try placing a return;尝试return; instead of a message.. this is working most browsers for me.而不是消息..这对我来说适用于大多数浏览器。 (This only really prevents dialog's presents) (这只会真正阻止对话的礼物)

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

Angular 9 approach: Angular 9 方法:

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

Browsers support and the removal of the custom message:浏览器支持和删除自定义消息:

  • Chrome removed support for the custom message in ver 51 min Chrome 在 51 分钟内取消了对自定义消息的支持
  • Opera removed support for the custom message in ver 38 min Opera 在 38 分钟内删除了对自定义消息的支持
  • Firefox removed support for the custom message in ver 44.0 min Firefox 在 ver 44.0 min 中删除了对自定义消息的支持
  • Safari removed support for the custom message in ver 9.1 min Safari 在版本 9.1 中移除了对自定义消息的支持

I faced the same problem, I was ok to get its own dialog box with my message, but the problem I faced was : 1) It was giving message on all navigations I want it only for close click.我遇到了同样的问题,我可以用我的消息获得自己的对话框,但我面临的问题是:1)它在所有导航上都给出了消息,我只需要点击即可。 2) with my own confirmation message if user selects cancel it still shows the browser's default dialog box. 2) 使用我自己的确认消息,如果用户选择取消,它仍会显示浏览器的默认对话框。

Following is the solutions code I found, which I wrote on my Master page.以下是我找到的解决方案代码,我写在我的母版页上。

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;

You can detect which button (ok or cancel) pressed by user, because the onunload function called only when the user choise leaveing the page.您可以检测用户按下了哪个按钮(确定或取消),因为只有在用户选择离开页面时才会调用 onunload 函数。 Althoug in this funcion the possibilities is limited, because the DOM is being collapsed.尽管在此功能中可能性是有限的,因为 DOM 正在折叠。 You can run javascript, but the ajax POST doesn't do anything therefore you can't use this methode for automatic logout.您可以运行 javascript,但 ajax POST 不执行任何操作,因此您不能使用此方法进行自动注销。 But there is a solution for that.但是有一个解决方案。 The window.open('logout.php') executed in the onunload funcion, so the user will logged out with a new window opening. window.open('logout.php') 在 onunload 函数中执行,因此用户将注销并打开一个新窗口。

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

This code called when user leave the page or close the active window and user logged out by 'logout.php'.当用户离开页面或关闭活动窗口并且用户通过“logout.php”注销时调用此代码。 The new window close immediately when logout php consist of code:注销php时新窗口立即关闭,代码如下:

window.close();

What about to use the specialized version of the "bind" command "one".如何使用“绑定”命令“一”的专用版本。 Once the event handler executes the first time, it's automatically removed as an event handler.事件处理程序第一次执行后,它会作为事件处理程序自动删除。

$(window).one("beforeunload", BeforeUnload);
 <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>

refer from http://www.codeprojectdownload.comhttp://www.codeprojectdownload.com参考

Try this尝试这个

$(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;
        });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM