检测浏览器或标签关闭

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

750701 次浏览

如果我没说错,你想知道什么时候一个标签/窗口是有效关闭的。好吧,在JavaScript中检测它的唯一方法是使用onunloadonbeforeunload事件。

不幸的是(或幸运的是?),当您通过链接或浏览器的后退按钮离开网站时,这些事件也会被触发。所以这是我能给出的最好答案,我不认为你可以在JavaScript中本机检测纯close。如果我说错了,请指正。

<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中是有效的

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

MDN文档

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

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


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

本例处理所有浏览器。

< p >试试这个,

.我相信这对你有用
<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>

简单的解决方案

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

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

然而,我同意缺少真正的关闭事件是很糟糕的:例如,如果你想在真正关闭的情况下才在后端重置会话状态,这是一个问题。

window.onbeforeunload = function ()
{


if (isProcess > 0)
{
return true;
}


else
{
//do something
}
};

此功能在浏览器运行过程中关闭窗口或刷新页面时显示确认对话框。该函数适用于所有浏览器。你必须在ajax进程中设置isProcess var。

试试这个。它会起作用的。Jquery卸载方法。

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

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

if(myWindow.closed){do things}

< p >注意: 轮询任何东西通常都不是最佳解决方案。如果可能的话,应该使用window.onbeforeunload事件,唯一的警告是,如果你导航离开,它也会触发
window.addEventListener("beforeunload", function (e) {
var confirmationMessage = "tab close";


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

我需要在浏览器或选项卡关闭时自动注销用户,而不是当用户导航到其他链接时。我也不希望在发生这种情况时显示确认提示。在与此斗争了一段时间后,特别是与IE和Edge,以下是我在基于这个答案的方法后结束所做的(检查与IE 11, Edge, Chrome和Firefox一起工作)。

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

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

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

实现注意:我使用的是ASP。NET MVC 5和我取消注销在一个覆盖Controller.OnActionExecuted()方法。

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

测试以下版本: Firefox 57, Internet Explorer 11, Edge 41,最新的Chrome浏览器之一(它不会显示我的版本)

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

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


});

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

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

这是我的钢笔

<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>
正如@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();
}
};

};

在window的帮助下可以检查。在'unload'事件的事件处理程序中关闭,但超时使用是必需的(所以结果不能保证如果SMTH延迟或阻止窗口关闭):

JSFiddle的示例(测试在最新的Safari, FF, Chrome, Edge和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!';
}
}

由于没有人提到它(8年多以后):WebSocket可以是检测关闭选项卡的另一种有效方法。只要选项卡打开并指向主机,客户端就能够保持到主机的活动WebSocket连接。

警告:请注意,这个解决方案只适用于WebSocket不需要任何额外的重大开销的项目。

在合理的超时时间内(例如2分钟),服务器端可以在WebSocket断开连接后确定客户端已经离开,并执行所需的任何操作,例如删除上传的临时文件。(在我非常专业的用例中,我的目标是在WebSocket连接断开和所有CGI/FastCGI活动终止后三秒终止本地主机应用程序服务器 -任何其他保持活动的连接都不影响我。)

我有问题得到onunload事件处理程序与信标正常工作(由这个答案推荐)。关闭选项卡似乎不会触发信标,而打开选项卡则会以可能导致问题的方式触发信标。WebSocket更干净地解决了我遇到的问题,因为连接关闭的时间与选项卡关闭的时间大致相同,在应用程序中切换页面只是在延迟窗口内打开一个新的WebSocket连接。

//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上测试了它,发现可以工作

:)如果你觉得我的回答有帮助,请投票....

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

<body onUnload="LogOff()">

然后添加LogOff函数重定向到Account/LogOff,这是Asp中的内置方法。净MVC。现在,当我关闭浏览器或选项卡,它重定向到LogOff方法和用户必须登录时返回。我已经在Chrome和amp;Firefox。它确实有效!

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


}
});
}

onunload的答案。根据caniuse它是跨浏览器的。但并非所有浏览器的反应都一样。

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

developer.mozilla.org

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

:

onunload在页面关闭上执行只有。它甚至不会在页面刷新和导航到另一个页面时执行。

Firefox v86.0:

它根本不会执行。页面刷新,导航离开,关闭浏览器标签,关闭浏览器,什么都没有。

我的方法是:

  1. 使用onpopstate监听url中的变化,并将sessionStorage变量设置为1
  2. 监听页面加载并将sessionStorage变量设置为0
  3. beforeunload上,检查变量是否为0。如果是这样,这意味着用户正在关闭而不是改变url。

这仍然是一条迂回的路,但对我来说是有意义的

浏览器已经进行了更新,以便在用户离开应用程序时更好地调整用户。事件“visibilitychange”让你在页面从另一个选项卡隐藏或关闭时进行调整。您可以跟踪文档可见性状态。财产文件。visbilitystate将返回当前状态。您将需要跟踪标志的进出,但它更接近目标。

更新的浏览器支持这一点,但safari(正如我们所知)从来不符合标准。你可以使用' pagshow '和'pagehide'在safari中工作。

您甚至可以使用像sendBeacon这样的新API在标签关闭时向服务器发送单向请求,并且不应该期待响应。

我构建了一个类的快速端口,用于跟踪此情况。我不得不删除框架中的一些调用,所以它可能是bug,但这应该让你开始。

export class UserLoginStatus
{
/**
* This will add the events and sign the user in.
*/
constructor()
{
this.addEvents();
this.signIn();
}


/**
* This will check if the browser is safari.
*
* @returns {bool}
*/
isSafari()
{
if(navigator && /Safari/.test(navigator.userAgent) && /Chrome/.test(navigator.userAgent))
{
return (/Google Inc/.test(navigator.vendor) === false);
}
return false;
}


/**
* This will setup the events array by browser.
*
* @returns {array}
*/
setupEvents()
{
let events = [
['visibilitychange', document, () =>
{
if (document.visibilityState === 'visible')
{
this.signIn();
return;
}


this.signOut();
}]
];


// we need to setup events for safari
if(this.isSafari())
{
events.push(['pageshow', window, (e) =>
{
if(e.persisted === false)
{
this.signIn();
}
}]);


events.push(['pagehide', window, (e) =>
{
if(e.persisted === false)
{
this.signOut();
}
}]);
}


return events;
}


/**
* This will add the events.
*/
addEvents()
{
let events = this.setupEvents();
if(!events || events.length < 1)
{
return;
}


for(var i = 0, length = events.length; i < length; i++)
{
var event = events[i];
if(!event)
{
continue;
}


event[1].addEventListener(event[0], event[3]);
}
}


/**
*
* @param {string} url
* @param {string} params
*/
async fetch(url, params)
{
await fetch(url,
{
method: 'POST',
body: JSON.stringify(params)
});
}


/**
* This will sign in the user.
*/
signIn()
{
// user is the app
const url = '/auth/login';
let params = 'userId=' + data.userId;


this.fetch(url, params);
}


/**
* This will sign out the user.
*/
signOut()
{
// user is leaving the app


const url = '/auth/logout';
let params = 'userId=' + data.userId;


if(!('sendBeacon' in window.navigator))
{
// normal ajax request here
this.fetch(url, params);
return;
}


// use a beacon for a more modern request the does not return a response
navigator.sendBeacon(url, new URLSearchParams(params));
}
}

它可以用来提醒用户是否有数据未保存或类似的事情。当标签页关闭或浏览器关闭或网页刷新时,此方法有效。

除非用户没有与网页进行交互,否则它不会工作,这是一种对抗恶意网站.....的机制除非你至少在网站窗口上点击或触摸,否则不会弹出窗口。

<!DOCTYPE html>
<html>
<head>
</head>
<body>
<form>
<textarea placeholder = "Write...."></textarea>
</form>
<script type="text/javascript">
window.addEventListener('beforeunload', function (e) {
e.returnValue = '';
});
</script>
</body>
</html>