需求:僅在用戶按 F5 或 Ctrl+R 刷新時觸發邏輯,忽略地址欄回車、前進/後退、鏈接跳轉。
只能檢測**鍵盤觸發**的刷新,無法區分地址欄回車與腳本 `location.reload()`,因它們最終都觸發 `beforeunload` → `unload`,無差異標識。
document.addEventListener('keydown', function(e) {
e = e || window.event;
const isRefresh = (e.ctrlKey && e.key === 'r') || e.key === 'F5';
if (isRefresh) {
// 延遲執行,避免 alert 阻塞導致瀏覽器忽略 return false
setTimeout(() => {
console.log('檢測到鍵盤刷新操作');
// 此處可執行統計上報、確認彈窗等
}, 100);
// 若需阻止刷新(慎用):
// e.preventDefault(); // 現代瀏覽器多忽略
// return false;
}
});
| 操作 | 可檢測 | 說明 |
|---|---|---|
| F5 / Ctrl+R | ✅ | 鍵盤事件可攔截 |
| 地址欄回車 | ❌ | 無鍵盤事件,直接導航 |
| 右鍵菜單「重新加載」 | ❌ | 同上 |
| 前進/後退 | ❌ | 屬於歷史導航,可用 `pageshow`/`pagehide` 配合 `persisted` 判斷 |
| 腳本 `location.reload()` | ❌ | 無鍵盤事件 |
// 1. 頁面卸載前確認(適用所有離開方式)
window.addEventListener('beforeunload', e => {
if (hasUnsavedChanges) {
e.preventDefault();
e.returnValue = ''; // 觸發瀏覽器原生確認彈窗
}
});
// 2. 區分刷新 vs 關閉 vs 跳轉(需服務端配合)
// 客戶端生成唯一 pageViewId 存入 sessionStorage
// 刷新時 sessionStorage 保留,關閉標籤頁則清除
// 服務端記錄 pageViewId 最後活躍時間,超時視為關閉
結論:**純前端無法完美區分所有刷新來源**,工程上通常結合 `beforeunload` 確認 + 服務端會話標識綜合判斷。