在浏览器中,JavaScript/TypeScript 提供了几种方法来检测用户是否离开当前页面。以下是主要的几种方法:
1.beforeunload事件
这是最常用的方法,当用户尝试关闭页面、刷新页面或导航到其他页面时触发。
window.addEventListener('beforeunload', (event) => {
// 可以在这里执行一些清理工作
// 在现代浏览器中,自定义消息不再显示,但仍需要以下代码来触发确认对话框
event.preventDefault();
event.returnValue = ''; // Chrome 需要设置returnValue
// 注意:返回的字符串在大多数现代浏览器中不会显示给用户
return '您确定要离开此页面吗?';
});
2.unload事件
当页面实际上正在被卸载时触发。
window.addEventListener('unload', () => {
// 执行清理工作,但这里的代码执行时间有限
// 不能使用同步 XMLHttpRequest 或显示对话框
// 可以使用 Navigator.sendBeacon() 发送最终的分析数据
navigator.sendBeacon('/analytics', JSON.stringify({
event: 'page_unload',
timestamp: new Date().getTime()
}));
});
3.visibilitychange事件
当用户切换标签页或最小化浏览器窗口时触发,可以检测页面是否可见。
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'hidden') {
// 用户离开了当前页面(切换到其他标签或最小化窗口)
console.log('用户不再查看页面');
} else if (document.visibilityState === 'visible') {
// 用户回到了当前页面
console.log('用户正在查看页面');
}
});
4.pagehide事件
类似于 unload,但在浏览器的前进/后退缓存(bfcache)激活时也会触发。
window.addEventListener('pagehide', (event) => {
if (event.persisted) {
// 页面被放入了 bfcache
console.log('页面被缓存');
} else {
// 页面正在被卸载
console.log('页面正在卸载');
}
});
5. 使用pageshow事件检测返回
与 pagehide 相对应,当用户通过历史记录返回页面时触发。
window.addEventListener('pageshow', (event) => {
if (event.persisted) {
// 页面是从 bfcache 恢复的
console.log('页面从缓存恢复');
} else {
// 页面是新加载的
console.log('页面新加载');
}
});
注意事项
- 现代浏览器限制了 beforeunload 事件中显示自定义消息的能力,以防止滥用。
- 在 unload 和 beforeunload 事件处理程序中,大多数异步操作将不会完成。
- 对于需要在页面卸载时发送数据的情况,推荐使用 navigator.sendBeacon() 方法。
- 移动设备上的行为可能与桌面浏览器不同。
- 单页应用程序(SPA)需要额外的路由事件监听来检测页面切换。