区分浏览器关闭和刷新
作者:彼得潘北北
链接:https://www.jianshu.com/p/021beaeee526
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
有这样一个需求,关闭浏览器标签页之后,再次通过历史记录进入时不能直接进入,而是要重新登录之后才能再次进入。大家都知道,只有关闭整个浏览器,sessionStorage才会消失,关闭单个标签页是不会消失的,除非手动清空。查了一些相关的资料,实现了在关闭页面时清空sessionStorage,但是又发现了新bug,就是在快速刷新的情况下,也会清空sessionStorage从而跳到登录页(很奇葩的一种操作)。。
其实本身浏览器关闭和刷新没有区别的太开,网上也有很多人问到底怎么区分,这里会介绍两种方案,一种是借鉴网上大神的,主要就是区别了关闭和刷新,一种是根据后来测试提出来的bug修改的,在快速刷新的情况下,当然一般人不会疯狂的点f5,除了测试
先介绍几个会用到的事件
- onload:页面载入时触发
- onbeforeunload: 在即将离开页面(刷新或关闭)时触发
- onunload: 退出页面时触发,已经从服务器上读到了需要加载的新的页面,在即将替换掉当前页面时调用
页面加载时只执行onload
页面关闭时先执行onbeforeunload,最后onunload
页面刷新时先执行onbeforeunload,然后onload,最后onunload。
以下不做兼容处理,以chrome为例
方案1:
let _beforeUnload_time = 0, _gap_time = 0;
window.onunload = function (){
_gap_time = new Date().getTime() - _beforeUnload_time;
if(_gap_time <= 5){
// 刷新时onbeforeunload与onunload的时间差一般都远大于5
// 浏览器关闭
sessionStorage.clear()
} else {
// 浏览器刷新
}
}
window.onbeforeunload = function (){
// 刷新或关闭页面都会执行,且先于onunload执行
_beforeUnload_time = new Date().getTime();
};
以上方法完全可以区分刷新和关闭,但是在你按着f5不动的情况下,onbeforeunload与onunload的时间差也会小于5,从而执行了sessionStorage.clear(),以至跳到了登录页
方案2:
方案2是在方案1的基础上改造的,主要是onload事件,适用于你是关闭了页面还是刷新了页面还是通过历史记录又进入了页面
<!DOCTYPE html>
<html lang="en">
<script>
// 关闭页面清除session
// 判断关闭页面之后与再次点开页面得时间,刷新操作时间间隔在20ms,>2000ms时说明是非刷新操作
// 2000ms是通过关闭页面到点击历史纪录进入页面间隔得大概最短时间
var loadTime = function (){
_load_time = new Date().getTime();
unload_time = localStorage.getItem('unload_time')
localStorage.setItem('_load_time', _load_time);
localStorage.setItem('nowload',_load_time-unload_time);
const gap = _load_time-unload_time;
if(gap>2000){
sessionStorage.clear()
}
};
loadTime()
</script>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"
/>
<title>citic-robot-ui</title>
<link rel="icon" href="/favicon.ico" type="image/x-icon" />
</head>
<body>
<script>
let _beforeUnload_time = 0, _gap_time = 0, _load_time=0,unload_time =0 ;
window.onunload = function (){
unload_time = new Date().getTime()
localStorage.setItem('unload_time', unload_time);
}
</script>
</body>
</html>
方案2主要就是通过判断载入页面的时间(onload事件)和上次退出页面(onunload)之间的时间差,在每次退出页面(刷新或关闭)时,都往localStorage存值,在载入时取localStorage的值,并且取到载入时的时间与之相减,得到差值,从而判断用户是刷新操作还是关了页面又通过历史纪录进来的操作。方案2将onload事件放到了最上面,之所以这样做是避免受网络速度影响导致载入的时间或长或短从而无法控制在一个具体的范围内。