如何检测浏览器的后退或前进按钮哪一个被按下?
如何区分浏览器后退与前进按钮触发的导航
浏览器原生并没有提供直接区分后退/前进按钮的API,你提到的performance.navigation.type(已废弃)或PerformanceNavigationTiming.type只能判断是否属于历史导航(back_forward),但无法区分是后退还是前进。下面是两种可行的实现思路:
方法一:利用history.state跟踪历史位置
通过在history.state中存储当前历史栈的位置索引,结合popstate事件对比索引变化判断导航方向:
// 初始化历史位置索引(首次加载时) if (!history.state) { history.replaceState({ position: 0 }, document.title); } let currentPosition = history.state.position; // 监听历史导航事件 window.addEventListener('popstate', (event) => { const newPosition = event.state?.position; if (newPosition === undefined) return; if (newPosition < currentPosition) { console.log('触发了后退按钮'); // 执行后退相关业务逻辑 } else if (newPosition > currentPosition) { console.log('触发了前进按钮'); // 执行前进相关业务逻辑 } currentPosition = newPosition; }); // 重写pushState,自动更新位置索引 const originalPushState = history.pushState; history.pushState = function(state, title, url) { const newState = { ...state, position: currentPosition + 1 }; currentPosition = newState.position; originalPushState.call(this, newState, title, url); }; // 重写replaceState,保持当前位置索引不变 const originalReplaceState = history.replaceState; history.replaceState = function(state, title, url) { const newState = { ...state, position: currentPosition }; originalReplaceState.call(this, newState, title, url); };
方法二:维护自定义历史记录栈
手动记录用户的导航路径,通过对比自定义栈的索引变化判断方向:
const historyStack = [window.location.href]; let currentIndex = 0; window.addEventListener('popstate', () => { const currentUrl = window.location.href; const prevIndex = currentIndex; // 查找当前URL在自定义栈中的位置 currentIndex = historyStack.indexOf(currentUrl); if (currentIndex === -1) { // 处理直接输入URL的情况,添加到栈中 historyStack.push(currentUrl); currentIndex = historyStack.length - 1; return; } if (currentIndex < prevIndex) { console.log('触发了后退按钮'); } else if (currentIndex > prevIndex) { console.log('触发了前进按钮'); } }); // 监听同域链接点击,更新自定义栈(模拟浏览器默认行为) document.addEventListener('click', (e) => { const link = e.target.closest('a'); if (link && link.href && link.origin === window.location.origin) { e.preventDefault(); const url = link.href; history.pushState(null, '', url); // 清空当前索引之后的栈元素(覆盖原有前进记录) historyStack.splice(currentIndex + 1); historyStack.push(url); currentIndex = historyStack.length - 1; // 这里可添加页面内容更新逻辑 } });
注意事项
两种方法均存在局限性:无法完全覆盖所有极端场景(如用户直接修改地址栏URL、通过控制台调用history.back()/forward()等),但能处理绝大多数由浏览器按钮、快捷键触发的常规导航场景。
内容的提问来源于stack exchange,提问作者buencamino
相关产品推荐
相关产品推荐

