当我们刷新页面(F5或浏览器中的图标)时,它将首先显示 触发ONUNLOAD事件。当我们关闭浏览器时(右上方的图标上的X),它会 触发ONUNLOAD事件。 现在,当触发ONUNLOAD事件时,无法区分刷新页面或关闭浏览器。 如果您有任何解决方案,请给我。
答案 0 :(得分:42)
有一个解决方案。
我希望在关闭选项卡或浏览器窗口时断开服务器上的用户连接,但是在重新加载页面时不要断开连接(您可能希望区分重新加载/关闭事件以用于其他目的,但您可以从我的解决方案中受益) 。基于HTML5的本地存储和客户端/服务器AJAX通信,我最终得到了以下过程:
,将onunload
添加到window
以下处理程序(伪javascript):
function myUnload(event) {
if (window.localStorage) {
// flag the page as being unloading
window.localStorage['myUnloadEventFlag']=new Date().getTime();
}
// notify the server that we want to disconnect the user in a few seconds (I used 5 seconds)
askServerToDisconnectUserInAFewSeconds(); // synchronous AJAX call
}
,在onload
上添加body
到以下处理程序(pseudo-javascript):
function myLoad(event) {
if (window.localStorage) {
var t0 = Number(window.localStorage['myUnloadEventFlag']);
if (isNaN(t0)) t0=0;
var t1=new Date().getTime();
var duration=t1-t0;
if (duration<10*1000) {
// less than 10 seconds since the previous Unload event => it's a browser reload (so cancel the disconnection request)
askServerToCancelDisconnectionRequest(); // asynchronous AJAX call
} else {
// last unload event was for a tab/window close => do whatever you want (I do nothing here)
}
}
}
在服务器上,收集列表中的断开连接请求,并设置一个定时器线程,定期检查列表(我每隔20秒使用一次)。一旦断开请求超时(即5秒消失),断开用户与服务器的连接。如果在此期间收到断开请求取消,则从列表中删除相应的断开连接请求,以便不断开用户。
如果要区分选项卡/窗口关闭事件和后续链接或提交的表单,此方法也适用。您只需要在包含链接和表单的每个页面上以及每个链接/表单登录页面上放置两个事件处理程序。
请注意,我使用unload
事件代替beforeUnload
事件,以便正确管理指向附件的链接:当用户点击指向附件的链接(例如PDF文件)时,{调度{1}}事件,然后引发打开/保存弹出窗口,仅此而已(浏览器不会更改显示的页面,也不会调度beforeUnload
事件)。如果我使用unload
事件(就像我之前做过的那样),那么当没有页面更改时,我会检测到页面更改。
此方法仅限于支持HTML5本地存储的浏览器,因此您可能会使用旧版浏览器(如MSIE7)的特定方法。
基于beforeUnload
的其他方法不可靠,因为当单击重新加载或选项卡/窗口关闭按钮时此值为负,而当使用键盘快捷键重新加载时为正(例如F5,Ctrl-R, ...)和窗口关闭(例如Alt-F4)。依靠事件X的位置也不可靠,因为按钮没有放在每个浏览器的相同位置(例如左边的关闭按钮)。
答案 1 :(得分:6)
不幸的是,正如此处的一些答案所示,检查事件的clientY
/ pageY
值并不是确定unload
事件是否被触发的可靠方法由于用户关闭页面。
单击浏览器的关闭按钮时clientY
/ pageY
为负的原因是因为关闭按钮位于文档顶部上方(即像素0上方),但重新加载也是如此按钮意味着点击重新加载按钮也会导致clientY
/ pageY
的值为负值。
沿着检查事件的x坐标的路径也是有问题的,因为浏览器关闭按钮并不总是在窗口的右侧(例如,它在OS X的左侧)并且因为窗口可以通过关闭其标签或键盘来关闭。
答案 2 :(得分:2)
不幸的是,目前尚无建议或可靠的方法。
答案 3 :(得分:1)
今天我遇到了同样的问题,并找到了我想与您分享的可能解决方案。
在考虑什么可以帮助辨别刷新和关闭时,我想到了cookie。我记得在没有明确到期日期的情况下设置cookie,使其仅适用于当前会话。在浏览器关闭之前,当前会话显然有效。这不包括关闭选项卡,但我的问题是关于用户身份验证,我不想仅为关闭选项卡而注销用户(我认为这与ASP.NET的ASPXAUTH
cookie的方法相同)。
所以,当用户登录并在页面加载时检查它时,我在document.cookies
集合中放了一个简单的cookie:如果cookie仍然存在,那么它是一个刷新或重新打开的选项卡,并保留用户数据,如果cookie当前会话已过期,因此用户数据已清除(与显式注销相同)。
希望这种方法对其他人有用!
答案 4 :(得分:1)
也许有人还在寻找答案...
您可以使用 SessionStorage !当页面重新加载但关闭时,未清除 SessionStorage。因此,基本上,您可以在加载页面时设置键/值对,但是在此之前,您需要检查键/值对是否存在。如果确实存在,则表示页面已重新加载;如果不存在,则意味着用户是首次打开页面或在新标签页中打开了页面。
if (sessionStorage.getItem('reloaded') != null) {
console.log('page was reloaded');
} else {
console.log('page was not reloaded');
}
sessionStorage.setItem('reloaded', 'yes');
这样,您可以doStuff()
处理onunload
事件(用户离开页面),如果设置了键/值对(用户重新加载页面),则otherStuff()
。 >
答案 5 :(得分:0)
使用window.onbeforeunload事件使案例离开页面,但它将包括刷新或锚标签....使用相同的验证标志,该过程的一个示例是URL检查(初始URL =当前URL)或F5使用keycode进行刷新检查,如果是锚标签,则使用bind()
注意*如果是Chrome,Keycode可能会导致问题。
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Test Page</title>
<style type='text/css'>
body {
font-family: sans-serif;
}
</style>
<script src="jquery-1.9.1.js" type='text/javascript'></script>
<script type='text/javascript'>
var valid=false;
function wireUpEvents() {
if(valid){
alert("Page Refreshed or Redirected");
}else{
window.onbeforeunload = askWhetherToClose;
}
function askWhetherToClose(event) {
if(!valid){
var msg;
msg = "You're leaving the page, do you really want to?";
event = event || window.event;
event.returnValue = msg;
return msg;
}}
$(document).bind('keypress', function(e) {
if (e.keyCode == 116){
// or you can insert some code to check page refresh
valid = true;
//wireUpEvents();
}
});
$("a").bind("click", function() {
//To check redirection using Anchor tags
valid = true;
//wireUpEvents();
});
}
$(document).ready(function() {
wireUpEvents();
});
</script>
</head>
<body>
<p>Close the browser window, or navigate to <a href="http://stackoverflow.com">StackOverflow</a></p>
</body>
</html>
答案 6 :(得分:0)
它是可行的解决方案
export class BootstrapComponent implements OnInit {
validNavigation = 0;
constructor(
private auth: AuthenticationService
) { }
ngOnInit() {
const self = this;
self.registerDOMEvents();
}
registerDOMEvents() {
const self = this;
window.addEventListener('unload', () => {
if (self.validNavigation === 0) {
self.endSession();
}
});
document.addEventListener('keydown', (e) => {
const key = e.which || e.keyCode;
if (key === 116) {
self.validNavigation = 1;
}
});
}
endSession() {
const self = this;
self.auth.clearStorage();
}
}
答案 7 :(得分:0)
贷记到https://www.anandkanatt.com/how-do-i-detect-browser-window-closed-refreshed/#comment-15892。我通过使用开瓶器本身进行了一些简化。在Chrome版本78.0.3887.7中进行了测试。
您可以尝试以下方法:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Processing...</title>
</head>
<body>
<script>
if (this.opener) {
// the opener was refreshed, do something if you want
} else {
// the opener was closed, do something if you want
}
// you may want to close the pop up
this.close()
</script>
</body>
</html>
window.addEventListener('unload', () => {
open('refresh-close-detector.html', '', 'width=100,height=100');
})
答案 8 :(得分:0)
这是一个巨大的黑客,有一些限制,但在大多数实际情况下都可以使用。
因此,如果您只需要在用户使用ctrl
+ r
或cmd
+ r
快捷方式时可以使用的功能,则可以跟踪{{1}当重新加载/关闭时您需要执行的操作被按下时,按}。
只需创建r
和keydown
事件侦听器即可切换keyup
变量。
rDown
然后,您有了“ onunload”事件侦听器,其中的侦听器函数具有一条let rDown = false;
window.addEventListener("keydown", event => {
if (event.key == 'r')
rDown = true;
})
window.addEventListener("keyup", event => {
if (event.key == 'r')
rDown = false;
})
语句,用于检查if
是否为rDown
。
true
答案 9 :(得分:-1)
我刚尝试了这个,它解决了这个问题: 创建一个sessionStorage对象,当用户关闭浏览器时,该对象将被销毁。我们可以检查sessionStorage对象以查找用户是否已关闭浏览器或刷新页面(sessionStorage对象在页面刷新时不会被销毁)。
答案 10 :(得分:-1)
--- 1 week ago ---
msg
msg
msg
msg
msg
----- today -----
msg
msg
msg
msg
使用if(window)确定是关闭还是仅重新加载。为我工作。
答案 11 :(得分:-2)
我早期的解决方案在IE中为我工作。对于除IE以外的浏览器,window.event将是未定义的,因为与其他浏览器不同,IE中的“事件”是全局定义的。在其他浏览器的情况下,您需要提供事件作为参数。另外,clientX没有为firefox定义,我们应该使用pageX。
尝试类似这样的东西....应该适用于IE和Firefox这个......
<html>
<body>
<script type="text/javascript">
window.onunload = function(e) {
// Firefox || IE
e = e || window.event;
var y = e.pageY || e.clientY;
if(y < 0) alert("Window closed");
else alert("Window refreshed");
}
</script>
</body>
</html>
答案 12 :(得分:-8)
<html>
<body onunload="doUnload()">
<script>
function doUnload(){
if (window.event.clientX < 0 && window.event.clientY < 0){
alert("Window closed");
}
else{
alert("Window refreshed");
}
}
</script>
</body>
</html>