是否有跨浏览器的JavaScript / jQuery代码来检测浏览器或浏览器选项卡是否已关闭,但不是由于单击链接而导致的?
sessionStorage
属性,它将在浏览器关闭时过期。w3schools.com/jsref/prop_win_sessionstorage.asp
是否有跨浏览器的JavaScript / jQuery代码来检测浏览器或浏览器选项卡是否已关闭,但不是由于单击链接而导致的?
sessionStorage
属性,它将在浏览器关闭时过期。w3schools.com/jsref/prop_win_sessionstorage.asp
Answers:
如果我正确地理解了您,您想知道何时有效关闭标签页/窗口。好吧,AFAIK Javascript
检测事件的唯一方法是onunload
&onbeforeunload
事件。
不幸的是(或幸运的是,)当您离开网站超过 link
或浏览器的后退按钮。因此,这是我能给出的最佳答案,我认为您无法从本机检测close
Java 脚本中的纯文本。如果我错了,请纠正我。
String
返回值onbeforeunload
。因此,现在您将不再能够在卸载之前显示自定义消息。
unload
?
由于某些原因,基于Webkit的浏览器不遵循该对话框的规范。一个几乎可以相互工作的示例与下面的示例非常接近。
window.addEventListener("beforeunload", function (e) {
var confirmationMessage = "\o/";
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Webkit, Safari, Chrome
});
此示例处理所有浏览器。
简单的解决方案
window.onbeforeunload = function () {
return "Do you really want to 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.onunload = "alert('wait')"
并window.onbeforeunload = "alert('wait... chrome!')"
使用了控制台,但在关闭标签页时均未触发。
window.onunload = "alert('wait')"
这样的赞不应该真的起作用。“该函数应为事件对象的returnValue属性分配一个字符串值,并返回相同的字符串”。请看一下MDN文章
我需要在浏览器或选项卡关闭时自动注销用户,但在用户导航到其他链接时不需要注销。我也不想在出现这种情况时显示确认提示。经过一段时间的努力之后,尤其是在IE和Edge上,我在此答案的基础上结束了我的工作(检查是否与IE 11,Edge,Chrome和Firefox配合使用)。
首先,beforeunload
在JS 中的事件处理程序中在服务器上启动一个倒数计时器。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()
方法取消注销。
OnActionExecuted
?
抱歉,我无法在现有答案之一中添加评论,但是如果您想实现一种警告对话框,我只想提及任何事件处理程序函数都有一个参数-event。对于您的情况,您可以调用event.preventDefault()来禁止自动离开页面,然后发出自己的对话框。我认为这比使用标准的丑陋和不安全的alert()方法更好。我亲自根据kendoWindow对象(Telerik的Kendo UI,几乎完全开源,除了kendoGrid和kendoEditor)实现了自己的对话框集。您还可以使用jQuery UI中的对话框。但是请注意,这些事情是异步的,您需要将处理程序绑定到每个按钮的onclick事件,但这都非常容易实现。
但是,我确实同意缺少真正的关闭事件是可怕的:例如,如果您只想在真正关闭的情况下想在后端重置会话状态,那就是一个问题。
对于类似的任务,您可以用来sessionStorage
在本地存储数据,直到关闭浏览器选项卡。
该sessionStorage
对象仅存储一个会话的数据(关闭浏览器选项卡时将删除该数据)。(W3Schools)
<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>
$(window).unload( function () { alert("Bye now!"); } );
beforeunload
是否要显示警报。像这样:$(window).on('beforeunload', function(){ alert ('Bye now')});
尝试使用它:
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;
});
});
我找到了一种方法,可以在所有浏览器上使用。
经过以下版本测试: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
}
};
});
由于尚无人提及它(8年后):WebSocket可以是检测关闭的选项卡的另一种有效方法。只要选项卡处于打开状态并指向主机,客户端就可以维持与主机的活动WebSocket连接。
注意:请注意,如果WebSocket不需要您已经在做的事情带来任何额外的大量开销,则该解决方案仅对项目才可行。
在合理的超时期限(例如2分钟)内,服务器端可以确定WebSocket断开连接后客户端已经离开,并执行所需的任何操作,例如删除上载的临时文件。(在我非常专业的用例中,我的目标是终止localhost应用服务器在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());
}
});
大家好,我能够通过使用浏览器本地存储和时间戳来实现“检测浏览器和选项卡关闭事件”的点击。希望大家使用此解决方案能解决您的问题。
经过初步研究,我发现当我们关闭浏览器时,浏览器将一一关闭所有选项卡以完全关闭浏览器。因此,我观察到在关闭标签之间几乎没有时间延迟。因此,我将此时间延迟作为主要验证点,并且能够实现浏览器和选项卡关闭事件检测。
我在Chrome浏览器76.0.3809.132版上对其进行了测试,发现可以正常工作
:)如果您发现我的回答有帮助,请投票。
window.onbeforeunload = function() {
console.log('event');
return false; //here also can be string, that will be shown to the user
}
here also can be string, that will be shown to the user
它在Firefox上没有,但是在chrome上有...
可以在像这样的'unload'事件中在事件处理程序中借助window.closed对其进行检查,但是需要使用超时(因此,如果延迟或阻止窗口关闭,则无法保证结果):
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!';
}
}
我已经尝试了所有上述解决方案,但没有一个对我真正有用,特别是因为我的项目中有一些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) {
}
});
}
window.onbeforeunload = function ()
{
if (isProcess > 0)
{
return true;
}
else
{
//do something
}
};
如果您在浏览器中的任何过程中关闭窗口或刷新页面,此函数都会显示一个确认对话框。此函数在所有浏览器中均有效。您必须在ajax进程中设置isProcess var。
window.addEventListener("beforeunload", function (e) {
var confirmationMessage = "tab close";
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
sendkeylog(confirmationMessage);
return confirmationMessage; //Webkit, Safari, Chrome etc.
});
sendkeylog
?
正如@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();
}
};
};
resize
当窗口模糊时,您将不断绑定。如果模糊100倍,那么您将有100个侦听器,这最终会降低浏览器的速度。
试试这个,我相信这对您有用。
<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>