如何精准判断用户是否离开当前页面?

4,644 阅读3分钟

一、为什么需要判断用户离开页面?

在现代 Web 应用中,用户离开页面的行为触发的场景包括:

  • 切换浏览器标签页 / 最小化窗口(页面不可见)

  • 关闭标签页 / 浏览器

  • 导航到新 URL

  • 移动端切换 App 或返回主屏幕

这类行为的监测直接关联用户体验优化、数据埋点、资源释放等核心需求,例如:

  • 暂停视频播放 / 动画以节省资源
  • 上报用户行为数据
  • 提示未保存数据的警告

二、核心检测方案与技术实现

方法一:Page Visibility API —— 现代浏览器的可见性监测标准

核心原理:通过监听页面可见性变化,判断用户是否切换标签页或最小化窗口。

// 监听页面可见性变化
document.addEventListener('visibilitychange', () => {
  if (document.hidden) {
    console.log('用户离开当前页面(标签页切换/窗口最小化)');
    // 执行资源释放操作
    pauseVideo();
    stopPolling();
  } else {
    console.log('用户返回当前页面');
    // 恢复操作
    resumeVideo();
    startPolling();
  }
});

适用场景

  • 视频 / 音频播放控制

  • 动画 / 轮播图暂停与恢复

  • 网络请求的暂停与续传

优缺点对比

方法二:beforeunload 与 unload 事件 —— 传统的页面卸载监听

**1. beforeunload 事件(离开前确认)**window.addEventListener('beforeunload', (event) => {

  // 防止未保存数据丢失(浏览器会显示默认确认框)
  event.preventDefault();
  event.returnValue = '确定要离开吗?未保存的数据将丢失';
  // 注意:现代浏览器会忽略returnValue,显示标准化提示
});

2. unload 事件(页面开始卸载时触发)

window.addEventListener('unload', () => {
  console.log('用户正在关闭或离开页面');
  // 警告:异步操作可能无法完成
  // sendAnalyticsData();  // 不推荐在此处发送网络请求
});

适用场景

  • 提示用户保存未完成的表单数据

  • 简单的资源清理(同步操作)

优缺点对比

方法三:navigator.sendBeacon () —— 可靠的数据上报方案

核心优势:解决 unload 事件中网络请求不可靠的问题,确保数据发送完成。

window.addEventListener('pagehide', () => {
  const analyticsData = {
    pageDuration: calculateStayTime(),
    lastAction: 'leave-page'
  };
  // 异步发送数据,不阻塞页面卸载
  navigator.sendBeacon('/analytics', JSON.stringify(analyticsData));
});

适用场景

  • 离开页面时的用户行为数据上报

  • 统计页面停留时间、最后操作等埋点数据

关键特性

  • 浏览器保证数据发送完成,即使页面已关闭
  • 支持 POST 请求,数据大小限制通常为 64KB
方法四:pagehide 与 pageshow 事件 —— 应对往返缓存(bfcache)

核心原理:监听页面进入 / 退出缓存状态,解决 unload 在 bfcache 下不触发的问题。

window.addEventListener('pagehide', (event) => {
  if (event.persisted) {
    console.log('页面进入往返缓存(点击后退/前进时缓存)');
  } else {
    console.log('页面正常卸载');
  }
  // 统一发送数据
  navigator.sendBeacon('/log', getExitData());
});

window.addEventListener('pageshow', (event) => {
  if (event.persisted) {
    console.log('页面从缓存中恢复');
    // 重新初始化页面状态
    resetPageState();
  }
});

适用场景

  • 移动端浏览器的页面缓存处理
  • 确保数据上报在所有卸载场景下触发

三、最佳实践与组合方案

  1. 可见性监测:优先使用 Page Visibility API 处理标签页切换场景。
  2. 数据上报:结合 pagehidenavigator.sendBeacon(),确保数据可靠发送。
  3. 防数据丢失:谨慎使用 beforeunload,仅在必要时提示用户保存数据。
  4. 资源管理:在 visibilitychange 中暂停非必要任务,在 pageshow 中恢复。

四、兼容性与性能优化

  • 浏览器兼容Page Visibility API 在 IE10+、Chrome、Firefox 等现代浏览器中全支持;sendBeacon() 在 IE11 + 及主流浏览器中可用。
  • 性能建议
    • 避免在 unload 中执行复杂逻辑或异步请求

    • visibilitychange 事件处理函数需轻量化,减少 DOM 操作

    • 数据上报使用 sendBeacon() 而非传统 XHR/fetch

通过组合运用上述 API,前端可以精准捕获用户离开页面的各类场景,在不影响性能的前提下实现智能化的用户行为响应,为应用体验优化和数据采集提供可靠支撑。