Javascript 检测浏览器或选项卡关闭

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3888902/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 06:30:54  来源:igfitidea点击:

Detect browser or tab closing

javascriptjquery

提问by cometta

Is there any cross-browser JavaScript/jQuery code to detect if the browser or a browser tab is being closed, but not due to a link being clicked?

是否有任何跨浏览器的 JavaScript/jQuery 代码来检测浏览器或浏览器选项卡是否被关闭,但不是由于点击了链接?

采纳答案by jAndy

If I get you correctly, you want to know when a tab/window is effectively closed. Well, AFAIK the only way in Javascriptto detect that kind of stuffs are onunload& onbeforeunloadevents.

如果我理解正确,您想知道标签/窗口何时有效关闭。好吧,AFAIKJavascript检测这种东西的唯一方法是onunload&onbeforeunload事件。

Unfortunately (or fortunately?), those events are also fired when you leave a site over a linkor your browsers back button. So this is the best answer I can give, I don't think you can natively detect a pure closein Javascript. Correct me if I'm wrong here.

不幸的是(或者幸运的是?),当您通过link浏览器的后退按钮离开站点时,这些事件也会被触发。所以这是我能给出的最好答案,我认为您无法close在 Javascript中原生检测到纯。如果我在这里错了,请纠正我。

回答by mohamed-ibrahim

From Firefox Documentation

来自Firefox 文档

For some reasons, Webkit-based browsers don't follow the spec for the dialog box. An almost cross-working example would be close from the below example.

由于某些原因,基于 Webkit 的浏览器不遵循对话框的规范。一个几乎交叉工作的例子与下面的例子很接近。

window.addEventListener("beforeunload", function (e) {
  var confirmationMessage = "\o/";

  (e || window.event).returnValue = confirmationMessage; //Gecko + IE
  return confirmationMessage;                            //Webkit, Safari, Chrome
});

This example for handling all browsers.

此示例用于处理所有浏览器。

回答by mohamed-ibrahim

Simple Solution

简单的解决方案

window.onbeforeunload = function () {
    return "Do you really want to close?";
};

回答by jyothis

<body onbeforeunload="ConfirmClose()" onunload="HandleOnClose()">

var myclose = false;

function ConfirmClose()
{
    if (event.clientY < 0)
    {
        event.returnValue = 'You have closed the browser. Do you want to logout from your application?';
        setTimeout('myclose=false',10);
        myclose=true;
    }
}

function HandleOnClose()
{
    if (myclose==true) 
    {
        //the url of your logout page which invalidate session on logout 
        location.replace('/contextpath/j_spring_security_logout') ;
    }   
}

//This is working in IE7, if you are closing tab or browser with only one tab

//这在 IE7 中有效,如果您关闭选项卡或只有一个选项卡的浏览器

回答by Ionian316

I needed to automatically log the user out when the browser or tab closes, but not when the user navigates to other links. I also did not want a confirmation prompt shown when that happens. After struggling with this for a while, especially with IE and Edge, here's what I ended doing (checked working with IE 11, Edge, Chrome, and Firefox) after basing off the approach by this answer.

我需要在浏览器或选项卡关闭时自动注销用户,但在用户导航到其他链接时不需要。我也不希望在发生这种情况时显示确认提示。在为此苦苦挣扎了一段时间后,尤其是使用 IE 和 Edge 之后,这就是我在基于此答案的方法之后结束的操作(检查了使用 IE 11、Edge、Chrome 和 Firefox 的工作)。

First, start a countdown timer on the server in the beforeunloadevent handler in JS. The ajax calls need to be synchronous for IE and Edge to work properly. You also need to use return;to prevent the confirmation dialog from showing like this:

首先,beforeunload在 JS中的事件处理程序中在服务器上启动一个倒数计时器。ajax 调用需要同步,IE 和 Edge 才能正常工作。您还需要使用return;来防止确认对话框显示如下:

    window.addEventListener("beforeunload", function (e) {        
      $.ajax({
          type: "POST",
          url: startTimerUrl,
          async: false           
      });
      return;
    });

Starting the timer sets the cancelLogoutflag to false. If the user refreshes the page or navigates to another internal link, the cancelLogoutflag on the server is set to true. Once the timer event elapses, it checks the cancelLogoutflag to see if the logout event has been cancelled. If the timer has been cancelled, then it would stop the timer. If the browser or tab was closed, then the cancelLogoutflag would remain falseand the event handler would log the user out.

启动计时器将cancelLogout标志设置为false。如果用户刷新页面或导航到另一个内部链接,cancelLogout则服务器上的标志设置为true。一旦计时器事件过去,它会检查cancelLogout标志以查看注销事件是否已被取消。如果计时器已被取消,那么它将停止计时器。如果浏览器或选项卡已关闭,则该cancelLogout标志将保持为false,并且事件处理程序会将用户注销。

Implementation note: I'm using ASP.NET MVC 5 and I'm cancelling logout in an overridden Controller.OnActionExecuted()method.

实施说明:我正在使用 ASP.NET MVC 5 并且我正在以重写的Controller.OnActionExecuted()方法取消注销。

回答by csandreas1

For similar tasks, you can use sessionStorageto store data locally until the browser tab is closed.

对于类似的任务,您可以使用sessionStorage本地存储数据,直到关闭浏览器选项卡。

The sessionStorageobject stores data for only one session (the data is deleted when the browser tab is closed).(W3Schools)

sessionStorage对象仅存储一个会话的数据(关闭浏览器选项卡时数据将被删除)。(W3Schools

This is my pen.

这是我的钢笔

<div id="Notice">
    <span title="remove this until browser tab is closed"><u>dismiss</u>.</span>
</div>
<script>
    $("#Notice").click(function() {
     //set sessionStorage on click
        sessionStorage.setItem("dismissNotice", "Hello");
        $("#Notice").remove();
    });
    if (sessionStorage.getItem("dismissNotice"))
    //When sessionStorage is set Do stuff...
        $("#Notice").remove();
</script>

回答by Alex Iurovetski

Sorry, I was not able to add a comment to one of existing answers, but in case you wanted to implement a kind of warning dialog, I just wanted to mention that any event handler function has an argument - event. In your case you can call event.preventDefault() to disallow leaving the page automatically, then issue your own dialog. I consider this a way better option than using standard ugly and insecure alert(). I personally implemented my own set of dialog boxes based on kendoWindow object (Telerik's Kendo UI, which is almost fully open-sourced, except of kendoGrid and kendoEditor). You can also use dialog boxes from jQuery UI. Please note though, that such things are asynchronous, and you will need to bind a handler to onclick event of every button, but this is all quite easy to implement.

抱歉,我无法对现有答案之一添加评论,但如果您想实现一种警告对话框,我只想提一下,任何事件处理函数都有一个参数 - event。在您的情况下,您可以调用 event.preventDefault() 禁止自动离开页面,然后发出您自己的对话框。我认为这是比使用标准的丑陋和不安全的 alert() 更好的选择。我个人基于 kendoWindow 对象(Telerik 的 Kendo UI,几乎完全开源,除了 kendoGrid 和 kendoEditor)实现了我自己的一组对话框。您还可以使用 jQuery UI 中的对话框。请注意,这些事情是异步的,您需要为每个按钮的 onclick 事件绑定一个处理程序,但这都很容易实现。

However, I do agree that the lack of the real close event is terrible: if you, for instance, want to reset your session state at the back-end only on case of the real close, it's a problem.

但是,我确实同意缺乏真正的关闭事件是可怕的:例如,如果您只想在真正关闭的情况下在后端重置会话状态,这是一个问题。

回答by dlsso

There is no event, but there is a property window.closedwhich is supported in all major browsers as of the time of this writing. Thus if you really needed to know you could poll the window to check that property.

没有事件,但在window.closed撰写本文时,所有主要浏览器都支持一个属性。因此,如果您真的需要知道您可以轮询窗口以检查该属性。

if(myWindow.closed){do things}

if(myWindow.closed){do things}

Note: Polling anything is generally not the best solution. The window.onbeforeunloadevent should be used if possible, the only caveat being that it also fires if you navigate away.

注意:轮询任何东西通常都不是最好的解决方案。window.onbeforeunload如果可能,应该使用该事件,唯一需要注意的是,如果您离开,它也会触发。

回答by Poonam Bhatt

$(window).unload( function () { alert("Bye now!"); } );

回答by Fezal halai

Try to use it:

尝试使用它:

window.onbeforeunload = function (event) {
    var message = 'Important: Please click on \'Save\' button to leave this page.';
    if (typeof event == 'undefined') {
        event = window.event;
    }
    if (event) {
        event.returnValue = message;
    }
    return message;
};

$(function () {
    $("a").not('#lnkLogOut').click(function () {
        window.onbeforeunload = null;
    });
    $(".btn").click(function () {
        window.onbeforeunload = null;
});
});