在 Web 開發(fā)中,我們經(jīng)常需要區(qū)分用戶是否通過刷新操作重新加載了頁面。這一操作可能是由用戶手動刷新(如按下 F5 鍵或點擊瀏覽器刷新按鈕)或通過瀏覽器自動重新加載。判斷頁面是否刷新有助于開發(fā)者優(yōu)化用戶體驗,例如在使用 vue 的時候需要進行權限控制,就需要判斷在刷新后根據(jù)登錄者的權限去添加對應的路由。
本文將詳細解析幾種常見的判斷頁面是否刷新的技術方案,并探討各自的適用場景、優(yōu)缺點以及瀏覽器的兼容性。
1. 使用 window.name
window.name
是一個持久的窗口屬性,它的值在頁面刷新、甚至通過標簽頁導航到其他頁面時也會保留,因此可以利用它來判斷頁面是否是通過刷新重新加載。
代碼示例
window.onload = function() {
if (window.name === 'isRefreshed') {
console.log('頁面被刷新');
} else {
console.log('首次加載頁面');
window.name = 'isRefreshed';
}
};
工作原理
優(yōu)點
缺點
兼容性
window.name
是一個非常老的 Web API,幾乎在所有瀏覽器中都有廣泛的支持,包括:
2. 使用 sessionStorage
sessionStorage
是 Web 存儲 API 的一部分,它為每個標簽頁維護獨立的存儲空間,并且其數(shù)據(jù)在標簽頁關閉后會被清空。我們可以利用 sessionStorage
來判斷頁面是否被刷新:
window.onload = function() {
if (sessionStorage.getItem('isRefreshed')) {
console.log('頁面被刷新');
} else {
console.log('首次加載頁面');
}
sessionStorage.setItem('isRefreshed', true);
};
工作原理
當頁面首次加載時,sessionStorage
中沒有 isRefreshed
條目,因此可以判斷這是首次加載。
通過設置 sessionStorage.setItem('isRefreshed', true);
,標記頁面已加載。
當頁面刷新后,sessionStorage
中的 isRefreshed
條目依然存在,因此可以檢測到頁面的刷新操作。
優(yōu)點
缺點
兼容性
sessionStorage
是廣泛支持的 API,適用于以下瀏覽器:
瀏覽器的 performance.navigation
API 提供了頁面加載的詳細信息,包括是否是通過刷新操作加載的頁面。通過檢查 performance.navigation.type
屬性可以判斷頁面的加載方式。
window.onload = function() {
if (performance.navigation.type === performance.navigation.TYPE_RELOAD) {
console.log('頁面被刷新');
} else {
console.log('首次加載頁面');
}
};
屬性解釋
優(yōu)點
直接提供了判斷頁面刷新與否的接口,較為精確。
不需要手動存儲狀態(tài)。
缺點
兼容性
performance.navigation
API 在大多數(shù)瀏覽器中都被支持,但該 API 已逐步被棄用:
4. 使用 beforeunload
事件
beforeunload
事件在用戶離開頁面之前觸發(fā),無論是頁面刷新、關閉還是導航到其他頁面。在此事件中,我們可以設置一個標志位來判斷用戶是否通過刷新離開當前頁面。
window.addEventListener('beforeunload', function() {
localStorage.setItem('isRefreshed', 'true');
});
window.onload = function() {
if (localStorage.getItem('isRefreshed') === 'true') {
console.log('頁面被刷新');
localStorage.removeItem('isRefreshed'); // 刷新后清除標志位
} else {
console.log('首次加載頁面');
}
};
工作原理
優(yōu)點
缺點
兼容性
beforeunload
事件在大多數(shù)現(xiàn)代瀏覽器中都有廣泛支持,但可能在一些移動端瀏覽器上表現(xiàn)不一致:
performance.getEntriesByType("navigation")
是一個現(xiàn)代 Web 性能 API,用于獲取頁面導航的詳細信息。通過這個方法,我們可以獲取一個包含導航信息的對象,并通過檢查該對象的 type
屬性,判斷頁面是通過刷新加載還是其他方式進入的。
示例代碼
window.onload = function() {
const [navigationEntry] = performance.getEntriesByType('navigation');
if (navigationEntry && navigationEntry.type === 'reload') {
console.log('頁面被刷新');
} else {
console.log('首次加載頁面');
}
};
工作原理
優(yōu)點
現(xiàn)代性:performance.getEntriesByType
是較新的 API,能夠在現(xiàn)代瀏覽器中準確區(qū)分頁面的導航方式。
詳細信息:除了判斷頁面刷新,還可以獲取更多關于頁面加載性能的數(shù)據(jù),如 DNS 解析時間、請求時間等,有助于調(diào)優(yōu)頁面性能。
無狀態(tài)管理:無需依賴 sessionStorage
、localStorage
等外部狀態(tài),避免了狀態(tài)同步問題。
缺點
使用場景
performance.getEntriesByType
適合那些只需要快速判斷頁面是否是刷新加載的場景,并且同時有進一步性能優(yōu)化需求的應用。對于現(xiàn)代 Web 開發(fā),這是一個較為精確且無需額外存儲或會話管理的解決方案。
監(jiān)控頁面加載性能示例
window.onload = function() {
const [navigationEntry] = performance.getEntriesByType('navigation');
if (navigationEntry) {
console.log(`頁面加載類型: ${navigationEntry.type}`);
console.log(`頁面加載時間: ${navigationEntry.loadEventEnd - navigationEntry.startTime} ms`);
}
};
這種方式不僅能幫助判斷頁面加載類型,還能幫助開發(fā)者優(yōu)化頁面性能,提供更多性能數(shù)據(jù)來分析頁面加載瓶頸。
兼容性
performance.getEntriesByType
是較新的 API,在現(xiàn)代瀏覽器中得到廣泛支持,但較舊瀏覽器不支持:
總結
判斷頁面是否刷新是一個常見的需求,本文介紹了五種技術方案。每種方案都有其特定的適用場景和優(yōu)缺點。總結如下:
方案 | 優(yōu)點 | 缺點 | 瀏覽器兼容性 |
---|
window.name | 簡單、易跨頁面保持狀態(tài) | 安全性問題,需手動清理 | 適用于所有現(xiàn)代瀏覽器 |
sessionStorage | 簡單,不依賴復雜邏輯 | 關閉標簽頁時清空 | 支持現(xiàn)代瀏覽器及部分較舊瀏覽器 |
performance.navigation | 直接提供頁面刷新判斷 | API 正被棄用 | 廣泛支持,但逐漸被廢棄 |
performance.getEntriesByType | 精確判斷加載類型 | 較新,舊版瀏覽器不支持 | 僅支持現(xiàn)代瀏覽器 |
beforeunload | 靈活,可處理多種離開頁面的操作 | 部分瀏覽器不支持,尤其是在移動端 | 大多數(shù)現(xiàn)代瀏覽器支持 |
不同的方案各有優(yōu)劣,開發(fā)者應根據(jù)應用的目標用戶群體、性能需求和瀏覽器支持情況靈活選擇。如果需要簡單、跨頁面的刷新判斷,window.name
是一個不錯的選擇;而在需要更精確、現(xiàn)代化的判斷方式時,performance.getEntriesByType
提供了更高的靈活性。