今日項目遇到一個問題,有一個功能會在瀏覽器的主窗口中新開一個窗口,然后業務要求:關閉新窗口的時候往后端發個請求,刷新的時候不發送。知道有個onbeforeunload事件是用於捕獲關閉瀏覽器事件(包括刷新)的,但刷新也會走此方法,所以行不通,於是就網上找了找資料,網上回答的最多的大致是這樣的
window.onbeforeunload = function() { //鼠標相對於用戶屏幕的水平位置 - 窗口左上角相對於屏幕左上角的水平位置 = 鼠標在當前窗口上的水平位置 var n = window.event.screenX - window.screenLeft; //鼠標在當前窗口內時,n<m,b為false;鼠標在當前窗口外時,n>m,b為true。20這個值是指關閉按鈕的寬度 var b = n > document.documentElement.scrollWidth-20; //鼠標在客戶區內時,window.event.clientY>0;鼠標在客戶區外時,window.event.clientY<0 if(b && window.event.clientY < 0 || window.event.altKey || window.event.ctrlKey){ //關閉瀏覽器時你想做的事 alert("關閉"); }else if(event.clientY > document.body.clientHeight || event.altKey){ //刷新瀏覽器時你想做的事 alert("刷新"); } }
但是,這個方法是監聽瀏覽器右上角的關閉事件的,我想要的是選項卡的關閉與刷新事件,下面我們先來分析一下關閉窗口相關的幾個方法
頁面關閉時先執行onbeforeunload,然后onunload
頁面刷新時先執行onbeforeunload,然后onunload,最后onload。
從上面的分析中,發現關閉與刷新都會走onbeforeunload與onunload,如果我們認為用這兩個方法無法區分關閉與刷新事件,那就大錯特錯了,正因為關閉與刷新事件都會走onbeforeunload與onunload,所以我們利用了一個關鍵點就能區分出這兩種,那就是:時間差
最終解決方法
var beginTime = 0;//執行onbeforeunload的開始時間 var differTime = 0;//時間差 window.onunload = function (){ differTime = new Date().getTime() - beginTime; if(differTime <= 5) { console.log("瀏覽器關閉") $.ajax({ type: "POST", url:url, dataType: "JSON", cache: false, success: function(msg){ console.log(msg); }, error:function(err){ console.log(err) } }) }else{ console.log("瀏覽器刷新") } } window.onbeforeunload = function (){ beginTime = new Date().getTime(); };
分析:雖然刷新與關閉都會走onbeforeunload與onunload,但可能因為刷新在加載新頁面前內部機制還需要做一些准備工作,所以刷新事件在執行到onunload事件時,用的時間會比關閉事件時間長,在我的測試頁面中,頁面里面沒啥內容,關閉時onbeforeunload與onunload的時間差一般會在3毫秒內,而刷新事件的時間差一般會在10毫秒以上,當我真正用到項目中的時候(真正的項目頁面中就有很多內容了),刷新事件的時間差竟能達到100毫秒左右,而關閉事件時間差還是3毫秒左右,這就大大保證了此方法的准確率,所以,判斷瀏覽器窗口或者說是選項卡的關閉與刷新,此方法是比較合適的。
原文鏈接:https://blog.csdn.net/itlsq/article/details/81095323