检测浏览器或制表符关闭

时间:2010-10-08 08:34:16

标签: javascript jquery

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

23 个答案:

答案 0 :(得分:235)

如果我找到你,你想知道什么时候有效关闭标签/窗口。好吧,AFAIK是Javascript检测此类内容的唯一方法onunload& onbeforeunload事件。

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

答案 1 :(得分:107)

来自Firefox Documentation

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

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

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

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

答案 2 :(得分:39)

简单解决方案

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

答案 3 :(得分:18)

<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') ;
    }   
}

//如果您只关闭一个标签

的标签或浏览器,这在IE7中有效

答案 4 :(得分:6)

我需要在浏览器或标签关闭时自动将用户注销,但不能在用户导航到其他链接时自动注销。当发生这种情况时,我也不希望显示确认提示。经过一段时间的努力,尤其是IE和Edge,这是我在this answer基于urlencode function的方法后所做的事情(检查使用IE 11,Edge,Chrome和Firefox)。 / p>

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

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

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

实施说明:我使用的是ASP.NET MVC 5,并且我在覆盖的Controller.OnActionExecuted()方法中取消了注销。

答案 5 :(得分:6)

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

但是,我确实认为缺少真正的关闭事件是非常糟糕的:例如,如果您只想在真正关闭的情况下重置后端的会话状态,那就是一个问题。

答案 6 :(得分:4)

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

if(myWindow.closed){do things}

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

答案 7 :(得分:4)

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

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>

答案 8 :(得分:4)

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

答案 9 :(得分:1)

window.onbeforeunload = function() {
  console.log('event');
  return false; //here also can be string, that will be shown to the user
}

答案 10 :(得分:1)

可以在像这样的'unload'事件中在事件处理程序中借助window.closed对其进行检查,但是需要超时使用(因此,如果延迟或阻止窗口关闭,则无法保证结果):< / p>

Example of JSFiddle (Tested on lates Safari, FF, Chrome, Edge and IE11 )

var win = window.open('', '', 'width=200,height=50,left=200,top=50');
win.document.write(`<html>
   <head><title>CHILD WINDOW/TAB</title></head>
   <body><h2>CHILD WINDOW/TAB</h2></body>
</html>`);
win.addEventListener('load',() => {
    document.querySelector('.status').innerHTML += '<p>Child was loaded!</p>';
});
win.addEventListener('unload',() => {
    document.querySelector('.status').innerHTML += '<p>Child was unloaded!</p>';
    setTimeout(()=>{
        document.querySelector('.status').innerHTML +=  getChildWindowStatus();
    },1000);
});
win.document.close()
document.querySelector('.check-child-window').onclick = ()=> {
    alert(getChildWindowStatus());
}
function getChildWindowStatus() {
  if (win.closed) { 
      return 'Child window has been closed!';
  } else {
      return 'Child window has not been closed!';
  }
}

答案 11 :(得分:1)

由于尚无人提及它(8年后):WebSocket可以是检测闭合标签的另一种有效方法。只要选项卡处于打开状态并指向主机,客户端就可以维持与主机的活动WebSocket连接。

注意事项:请注意,如果WebSocket不需要您已经在做的事情带来任何额外的大量开销,则该解决方案实际上仅对项目可行。

在合理的超时期限(例如2分钟)内,服务器端可以确定在WebSocket断开连接后客户端已消失,并执行所需的任何操作,例如删除上载的临时文件。 (在我的非常专业的用例中,我的目标是在WebSocket连接断开并且所有CGI / FastCGI活动终止后三秒钟终止a localhost app server-其他任何保持活动的连接都不会影响我。)

我在使onunload事件处理程序与信标一起正常工作方面遇到问题(如this answer的建议)。关闭选项卡似乎没有触发信标,而打开选项卡则以可能导致问题的方式触发了它。 WebSocket解决了我遇到的问题,因为连接大致在选项卡关闭的同时关闭,并且在应用程序内切换页面只是在延迟窗口内很好地打开了一个新的WebSocket连接。

答案 12 :(得分:1)

尝试使用它:

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

答案 13 :(得分:1)

我已经尝试了所有上述解决方案,但都没有真正为我工作,特别是因为我的项目中有一些Telerik组件具有弹出窗口的“关闭”按钮,并且它称为“ beforeunload”事件。另外,当页面中有Telerik网格时,按钮选择器也无法正常工作(我的意思是网格内的按钮)。因此,我无法使用以上任何建议。最后,这是为我工作的解决方案。 我在_Layout.cshtml的body标签上添加了onUnload事件。像这样:

<body onUnload="LogOff()">

,然后添加LogOff函数以重定向到Account / LogOff,这是Asp.Net MVC中的内置方法。现在,当我关闭浏览器或选项卡时,它将重定向到LogOff方法,并且用户必须在返回时登录。我已经在Chrome和Firefox中对其进行了测试。而且有效!

  function LogOff() {
        $.ajax({
            url: "/Account/LogOff",
            success: function (result) {

                                        }
               });
       }

答案 14 :(得分:0)

window.onbeforeunload = function ()
{       

    if (isProcess > 0) 
    {
        return true;       
    }   

    else
    { 
        //do something      
    }
}; 

如果在浏览器的任何过程中关闭窗口或刷新页面,此函数会显示一个确认对话框。此功能适用于所有浏览器。您必须在ajax进程中设置isProcess var。

答案 15 :(得分:0)

docker version

答案 16 :(得分:0)

我找到了一种方法,适用于我的所有浏览器

测试以下版本: Firefox 57,Internet Explorer 11,Edge 41,其中一个经过验证的Chrome(它不会显示我的版本)

  

注意:如果您以任何可能的方式离开页面,都会触发onb​​eforeunload(刷新,关闭浏览器,重定向,链接,提交..)。如果您只希望它在浏览器关闭时发生,只需绑定事件处理程序。

  $(document).ready(function(){         

        var validNavigation = false;

        // Attach the event keypress to exclude the F5 refresh (includes normal refresh)
        $(document).bind('keypress', function(e) {
            if (e.keyCode == 116){
                validNavigation = true;
            }
        });

        // Attach the event click for all links in the page
        $("a").bind("click", function() {
            validNavigation = true;
        });

        // Attach the event submit for all forms in the page
        $("form").bind("submit", function() {
          validNavigation = true;
        });

        // Attach the event click for all inputs in the page
        $("input[type=submit]").bind("click", function() {
          validNavigation = true;
        }); 

        window.onbeforeunload = function() {                
            if (!validNavigation) {     
                // ------->  code comes here
            }
        };

  });

答案 17 :(得分:0)

正如@jAndy所提到的,没有适当的javascript代码来检测窗口是否关闭。 我从@Syno的建议开始。

我经历了这样的情况,只要您按照以下步骤操作,就可以检测到它。
我在Chrome 67+和Firefox 61+上进行了测试。

var wrapper = function () { //ignore this

var closing_window = false;
$(window).on('focus', function () {
    closing_window = false; 
   //if the user interacts with the window, then the window is not being 
   //closed
});

$(window).on('blur', function () {

    closing_window = true;
    if (!document.hidden) { //when the window is being minimized
        closing_window = false;
    }
    $(window).on('resize', function (e) { //when the window is being maximized
        closing_window = false;
    });
    $(window).off('resize'); //avoid multiple listening
});

$('html').on('mouseleave', function () {
    closing_window = true; 
    //if the user is leaving html, we have more reasons to believe that he's 
    //leaving or thinking about closing the window
});

$('html').on('mouseenter', function () {
    closing_window = false; 
    //if the user's mouse its on the page, it means you don't need to logout 
    //them, didn't it?
});

$(document).on('keydown', function (e) {

    if (e.keyCode == 91 || e.keyCode == 18) {
        closing_window = false; //shortcuts for ALT+TAB and Window key
    }

    if (e.keyCode == 116 || (e.ctrlKey && e.keyCode == 82)) {
        closing_window = false; //shortcuts for F5 and CTRL+F5 and CTRL+R
    }
});

// Prevent logout when clicking in a hiperlink
$(document).on("click", "a", function () {
    closing_window = false;
});

// Prevent logout when clicking in a button (if these buttons rediret to some page)
$(document).on("click", "button", function () {
    closing_window = false;

});
// Prevent logout when submiting
$(document).on("submit", "form", function () {
    closing_window = false;
});
// Prevent logout when submiting
$(document).on("click", "input[type=submit]", function () {
    closing_window = false;
});

var toDoWhenClosing = function() {

    //write a code here likes a user logout, example: 
    //$.ajax({
    //    url: '/MyController/MyLogOutAction',
    //    async: false,
    //    data: {

    //    },
    //    error: function () {
    //    },
    //    success: function (data) {
    //    },
    //});
};


window.onbeforeunload = function () {
    if (closing_window) {
        toDoWhenClosing();
    }
};

};

答案 18 :(得分:0)

//Detect Browser or Tab Close Events
$(window).on('beforeunload',function(e) {
  e = e || window.event;
  var localStorageTime = localStorage.getItem('storagetime')
  if(localStorageTime!=null && localStorageTime!=undefined){
    var currentTime = new Date().getTime(),
        timeDifference = currentTime - localStorageTime;

    if(timeDifference<25){//Browser Closed
       localStorage.removeItem('storagetime');
    }else{//Browser Tab Closed
       localStorage.setItem('storagetime',new Date().getTime());
    }

  }else{
    localStorage.setItem('storagetime',new Date().getTime());
  }
});

JSFiddle Link

大家好,我能够通过使用浏览器本地存储和时间戳来实现“检测浏览器和选项卡关闭事件”的点击。希望大家都可以通过使用该解决方案解决您的问题。

经过初步研究,我发现当我们关闭浏览器时,浏览器将逐个关闭所有选项卡以完全关闭浏览器。因此,我观察到在关闭标签之间几乎没有时间延迟。因此,我将此时间延迟作为主要验证点,并且能够实现浏览器和选项卡关闭事件检测。

我在Chrome浏览器76.0.3809.132版上对其进行了测试,发现可以正常运行

:)如果您认为我的回答有帮助,请投票。...

答案 19 :(得分:0)

onunload是答案。跨浏览器。

window.onunload = function(){alert("The window is closing now!");}

onunload仅在页面关闭时执行

这些事件在窗口卸载其内容和资源时触发。

我在chrome上进行了测试,即使在刷新页面和导航到其他页面时也无法执行。

由于javascript执行代码的方式,警报可能不会显示。但是肯定会击中代码。

答案 20 :(得分:-1)

试试这个, 我相信这对你有用。

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type='text/javascript'>
    $(function() {

        try{
            opera.setOverrideHistoryNavigationMode('compatible');
            history.navigationMode = 'compatible';
        }catch(e){}

        function ReturnMessage()
        {
            return "wait";
        }

        function UnBindWindow()
        {
            $(window).unbind('beforeunload', ReturnMessage);
        }

        $(window).bind('beforeunload',ReturnMessage );
    });
</script>

答案 21 :(得分:-2)

试试这个。它会工作。 jquery卸载方法已被删除。

window.onbeforeunload = function(event) {
    event.returnValue = "Write something clever here..";
};

答案 22 :(得分:-3)

Date test = new Date();
String dayString = test.toString();
String timeString = dayString.substring( 11 , 19 );

我已在以下Web浏览器中测试过此脚本: 目前,Opera Web浏览器不支持onBeforeUnload事件。 IE浏览器 火狐浏览器 谷歌浏览器 Safari浏览器