Javascript/jquery:如何检测location.href跳转是页面卸载还是被新窗口/应用链接打开
实现方案
你可以通过页面可见性事件、页面卸载事件结合短时间阈值判断的方式解决这个问题,核心逻辑是:正常调用location.href触发页面跳转时,页面会在极短时间内触发beforeunload事件并卸载,后续绑定的页面可见性回调、定时器都不会执行;如果跳转被系统拦截、唤起第三方APP或者打开新窗口,当前页面会留存,后续回调和定时器可以正常执行。
方案1:可见性事件+跳转标记判断(兼容性最好)
// 支付跳转逻辑 function jumpToPay(payUrl) { // 存储跳转标记和时间戳 sessionStorage.setItem('pending_pay_jump', '1'); sessionStorage.setItem('jump_timestamp', Date.now().toString()); // 执行跳转 location.href = payUrl; } // 正常跳转卸载时清除标记 window.addEventListener('beforeunload', () => { sessionStorage.removeItem('pending_pay_jump'); sessionStorage.removeItem('jump_timestamp'); }); // 监听页面可见性变化 document.addEventListener('visibilitychange', () => { if (document.visibilityState === 'visible') { const hasPendingJump = sessionStorage.getItem('pending_pay_jump'); const jumpTime = Number(sessionStorage.getItem('jump_timestamp') || 0); // 存在跳转标记且跳转时间距当前小于3秒(阈值可按需调整) if (hasPendingJump && Date.now() - jumpTime < 3000) { // 清理标记 sessionStorage.removeItem('pending_pay_jump'); sessionStorage.removeItem('jump_timestamp'); // 可替换为订单状态查询逻辑,不需要全量刷新可以不用reload location.reload(); } } });
方案2:定时器兜底判断
function jumpToPay(payUrl) { let isPageUnloaded = false; // 监听卸载事件标记 const unloadHandler = () => isPageUnloaded = true; window.addEventListener('beforeunload', unloadHandler); location.href = payUrl; // 500ms后检查页面是否留存 setTimeout(() => { window.removeEventListener('beforeunload', unloadHandler); if (!isPageUnloaded) { // 标记需要切回刷新 sessionStorage.setItem('refresh_on_back', '1'); } }, 500); } // 切回页面时触发刷新 document.addEventListener('visibilitychange', () => { if (document.visibilityState === 'visible' && sessionStorage.getItem('refresh_on_back')) { sessionStorage.removeItem('refresh_on_back'); location.reload(); } });
注意事项
- 时间阈值可根据业务场景调整,网络较慢的场景可以适当放大到5秒
- 若不需要全量刷新页面,可将
location.reload()替换为订单状态查询接口调用,用户体验更好 - 所有标记存在
sessionStorage中,关闭页面会自动清空,不会产生残留污染
内容的提问来源于stack exchange,提问作者Tobia
相关产品推荐
相关产品推荐

