區(qū)分瀏覽器關(guān)閉和刷新
有這樣一個(gè)需求,關(guān)閉瀏覽器標(biāo)簽頁之后铅歼,再次通過歷史記錄進(jìn)入時(shí)不能直接進(jìn)入公壤,而是要重新登錄之后才能再次進(jìn)入。大家都知道椎椰,只有關(guān)閉整個(gè)瀏覽器厦幅,sessionStorage才會(huì)消失,關(guān)閉單個(gè)標(biāo)簽頁是不會(huì)消失的慨飘,除非手動(dòng)清空慨削。查了一些相關(guān)的資料,實(shí)現(xiàn)了在關(guān)閉頁面時(shí)清空sessionStorage套媚,但是又發(fā)現(xiàn)了新bug缚态,就是在快速刷新的情況下,也會(huì)清空sessionStorage從而跳到登錄頁(很奇葩的一種操作)堤瘤。玫芦。
其實(shí)本身瀏覽器關(guān)閉和刷新沒有區(qū)別的太開,網(wǎng)上也有很多人問到底怎么區(qū)分本辐,這里會(huì)介紹兩種方案桥帆,一種是借鑒網(wǎng)上大神的医增,主要就是區(qū)別了關(guān)閉和刷新,一種是根據(jù)后來測(cè)試提出來的bug修改的老虫,在快速刷新的情況下叶骨,當(dāng)然一般人不會(huì)瘋狂的點(diǎn)f5,除了測(cè)試
先介紹幾個(gè)會(huì)用到的事件
- onload:頁面載入時(shí)觸發(fā)
- onbeforeunload: 在即將離開頁面(刷新或關(guān)閉)時(shí)觸發(fā)
- onunload: 退出頁面時(shí)觸發(fā)祈匙,已經(jīng)從服務(wù)器上讀到了需要加載的新的頁面忽刽,在即將替換掉當(dāng)前頁面時(shí)調(diào)用
頁面加載時(shí)只執(zhí)行onload
頁面關(guān)閉時(shí)先執(zhí)行onbeforeunload,最后onunload
頁面刷新時(shí)先執(zhí)行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){
// 刷新時(shí)onbeforeunload與onunload的時(shí)間差一般都遠(yuǎn)大于5
// 瀏覽器關(guān)閉
sessionStorage.clear()
} else {
// 瀏覽器刷新
}
}
window.onbeforeunload = function (){
// 刷新或關(guān)閉頁面都會(huì)執(zhí)行伞剑,且先于onunload執(zhí)行
_beforeUnload_time = new Date().getTime();
};
以上方法完全可以區(qū)分刷新和關(guān)閉,但是在你按著f5不動(dòng)的情況下市埋,onbeforeunload與onunload的時(shí)間差也會(huì)小于5黎泣,從而執(zhí)行了sessionStorage.clear(),以至跳到了登錄頁
方案2:
方案2是在方案1的基礎(chǔ)上改造的缤谎,主要是onload事件抒倚,適用于你是關(guān)閉了頁面還是刷新了頁面還是通過歷史記錄又進(jìn)入了頁面
<!DOCTYPE html>
<html lang="en">
<script>
// 關(guān)閉頁面清除session
// 判斷關(guān)閉頁面之后與再次點(diǎn)開頁面得時(shí)間,刷新操作時(shí)間間隔在20ms弓千,>2000ms時(shí)說明是非刷新操作
// 2000ms是通過關(guān)閉頁面到點(diǎn)擊歷史紀(jì)錄進(jìn)入頁面間隔得大概最短時(shí)間
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主要就是通過判斷載入頁面的時(shí)間(onload事件)和上次退出頁面(onunload)之間的時(shí)間差衡便,在每次退出頁面(刷新或關(guān)閉)時(shí),都往localStorage存值洋访,在載入時(shí)取localStorage的值镣陕,并且取到載入時(shí)的時(shí)間與之相減,得到差值姻政,從而判斷用戶是刷新操作還是關(guān)了頁面又通過歷史紀(jì)錄進(jìn)來的操作呆抑。方案2將onload事件放到了最上面,之所以這樣做是避免受網(wǎng)絡(luò)速度影響導(dǎo)致載入的時(shí)間或長(zhǎng)或短從而無法控制在一個(gè)具體的范圍內(nèi)汁展。