场景细分:
- 切换到其他浏览器标签页或应用(页面变为不可见,但未关闭)。
- 最小化浏览器窗口
- 关闭浏览器标签页或整个浏览器
- 在当前标签页中导航到新的 URL
- 在移动设备上切换到其他 App 或返回主屏幕
- 方法一:Page Visibility API (页面可见性API) --现代首选
“页面是否用户可见” ,检测页面是否被隐藏或者显示。非常适合用户切换标签页、最小化窗口登场景
* 核心概念:
* document.hidden: 一个只读属性。如果页面处于后台或者最小化,值为true,否则返回false
* visilibitychange事件:当页面的可见性状态发生变化的时候,该事件会在document对象上触发
* 适用场景:
* 暂停/播放视频或音频。
* 停止/启动动画或轮播图。
* 暂停轮询服务器请求,在页面恢复可见时再继续。
* 示例代码:
document.addEventListener('visilibitychange',()=>{
if (document.hidden) {
// 页面变得不可见
console.log('用户离开了当前页面(切换标签页或最小化)');
// 在这里暂停视频、动画等
pauseMyVideo();
} else {
// 页面恢复可见
console.log('用户回到了当前页面');
// 在这里恢复播放
playMyVideo();
}
* 优点:
* 可靠性高,W3C标准,所有当代浏览器都支持
* 性能友好
* 逻辑清晰:直接反映页面可见状态
* 缺点:
* 无法判断用户是否正在“关闭”页面。当用户关闭标签页时,`visibilitychange` 事件可能会触发(变为 hidden),但我们无法区分这是切换还是关闭
- 方法二:beforeunload 和 unload事件 --传统方法
- 这两个事件是在用户真正离开页面(关闭,刷新,导航到其他连接时候触发)
1. beforeunload事件
- 该事件在窗口、文档及其资源即将被卸载时触发,用来询问用户是否要离开
- 用途
- 方式用户意外离开导致未保存的数据丢失
- 示例代码
window.addEventListener('beforeload',(e)=>{
e.returnValue ="您有未保存的数据,确定要离开吗"
})
// 注意:出于安全考虑,现代浏览器不允许开发者自定义提示框的文本内容。只会显示浏览器内置的标准化提示
2. unload事件
- 该事件在页面已经开始卸载之后触发。
window.addEventListener('unload', () => {
console.log('用户正在关闭或离开页面');
// 警告:在这里执行的操作可能不会完成!
// sendAnalyticsData();
});
- 重大缺陷:非常不可靠,浏览器处理卸载的时候,并不会等待`unload` 事件处理器中的异步操作(如 `fetch` 或 `XMLHttpRequest`)完成。这意味着,如果我们想在这里发送一个分析数据到服务器,这个请求很可能在发送完成之前就被浏览器终止了。
方法3:navigator.sendBeacon() - 可靠的数据上报利器
- sendBeacon() 可以异步向服务器发送数据,并浏览器保证会将其启动并排队发送。不会阻塞或者延迟页面的卸载过程,即使页面已经关闭,数据发送也会在后台继续进行
- 使用场景:用户离开页面时,可靠地发送日志、分析或统计数据。