监听浏览器刷新事件,拦截浏览器返回,js监听移动端浏览器页面显示、隐藏

以下是针对你的问题“监听浏览器刷新事件、拦截浏览器返回、JS监听移动端浏览器页面显示/隐藏”的完整、实用总结(基于2025–2026年浏览器现状)。

这些需求在现代浏览器中都有不同程度的限制,不能100%拦截,但可以实现大部分场景。

1. 监听 / 拦截浏览器刷新(F5、Ctrl+R、浏览器刷新按钮)

核心结论
无法真正“阻止刷新”而不弹出确认框(现代浏览器不允许无感拦截)。
能做的是:弹出确认对话框(“是否离开页面?”),用户点“取消”才不刷新。

// 推荐写法(兼容现代浏览器 2025+)
window.addEventListener('beforeunload', (event) => {
  // 只有在需要阻止时才触发确认
  const shouldWarn = /* 你的条件,比如表单有未保存内容 */;

  if (shouldWarn) {
    event.preventDefault();          // 必须调用(Chrome/Edge/Firefox 2025+ 要求)
    event.returnValue = '';          // 必须设置(兼容旧浏览器 + 触发确认框)

    // 现代浏览器(Chrome 51+、Safari 等)**忽略自定义字符串**,只会显示浏览器默认文案:
    // "此站点要求你确认是否离开..." 或 "更改可能不会保存"
  }
});

// 或者更老的兼容写法(部分浏览器仍需)
window.onbeforeunload = function() {
  return "你的更改可能不会保存,确定要刷新/离开吗?";
  // 但2025+ Chrome 等已忽略自定义消息,只显示默认提示
};

注意事项

  • 必须有用户交互(点击、输入等),否则 Chrome 会静默阻止弹窗(Blocked attempt to show beforeunload…)
  • 移动端表现一致,但部分 Android 浏览器可能延迟或不弹
  • 完全无感阻止刷新 → 不可能(安全限制)

检测是否是刷新(而非关闭标签或跳转) → 基本不可能可靠区分(beforeunload 触发原因不暴露)。

2. 拦截浏览器返回(后退按钮 / back)

核心结论
无法直接 preventDefault() 浏览器后退按钮(UI 触发的 navigation)。
但可以用 history 欺骗技巧 实现“假拦截”。

// 方法1:最常用“后退拦截”方案(适用于 SPA / 表单确认)
history.pushState(null, document.title, location.href);  // 先推一个“假”状态

window.addEventListener('popstate', (event) => {
  // 用户点了后退按钮(或调用 history.back())

  // 这里可以弹出确认框
  const confirmed = confirm("确定要返回上一页吗?未保存内容将丢失!");

  if (!confirmed) {
    // 不让后退 → 再推一次相同的状态,抵消这次 popstate
    history.pushState(null, document.title, location.href);
  } else {
    // 允许后退 → 什么都不做,或者 history.back()
    // history.back();  // 如果你想主动后退
  }
});

方法2:更现代的 Navigation API(Chrome/Edge 2023+ 支持,2025年已较完善)

if ('navigation' in window) {
  window.navigation.addEventListener('navigate', (event) => {
    if (event.canIntercept && event.hashChange === false) {
      // 可以拦截的导航(包括后退)
      event.intercept({
        handler: async () => {
          const confirmed = confirm("确定返回?");
          if (!confirmed) {
            // 不执行导航
            return;
          }
          // 否则继续
          await updatePage(event);
        }
      });
    }
  });
}

兼容性提示(2026年):

  • Safari 不支持 Navigation API → 仍需用 popstate 方案
  • 移动端 Chrome/Android 支持良好

3. 监听移动端浏览器页面显示 / 隐藏(可见性变化)

推荐使用 Page Visibility API(所有现代浏览器 2025+ 完美支持,包括 iOS Safari、Android Chrome)

// 监听页面可见性变化(切换 tab、切到后台、锁屏等)
function handleVisibilityChange() {
  if (document.visibilityState === 'visible') {
    console.log('页面显示(前台)');
    // 恢复轮询、视频播放、WebSocket 心跳等
  } else if (document.visibilityState === 'hidden') {
    console.log('页面隐藏(后台)');
    // 暂停轮询、视频、动画、释放资源、发送埋点等
  }
}

document.addEventListener('visibilitychange', handleVisibilityChange, false);

// 或者简写(推荐)
document.addEventListener('visibilitychange', () => {
  console.log(`当前状态: ${document.visibilityState}`); // visible / hidden
});

// 初始状态检查
console.log(`页面初始状态: ${document.visibilityState}`);

移动端特殊行为(2025–2026 现状):

  • Android Chrome:切到后台 → hidden(比较可靠)
  • iOS Safari:切到后台或锁屏 → hidden(但有时延迟,或长时间后台后不一定恢复 visible)
  • 长时间后台(>15分钟)→ 部分 Android 浏览器可能不触发 visible 恢复(系统冻结)
  • PWA(添加到主屏幕):行为更接近原生 App,hidden 触发更稳定

补充:监听切回前台的其他方式(作为 fallback)

// 辅助判断(不推荐作为主要方式)
window.addEventListener('focus',  () => console.log('窗口获得焦点'));
window.addEventListener('blur',   () => console.log('窗口失去焦点'));

快速总结表(2026 年推荐优先级)

需求推荐 API / 事件是否能完全阻止移动端可靠性备注
拦截刷新beforeunload只能弹确认框自定义消息已被浏览器忽略
拦截后退按钮popstate + history.pushState间接实现中–高Navigation API 更好但兼容性稍差
页面显示/隐藏visibilitychange首选,省电、暂停资源神器

最常用组合写法(表单未保存时保护):

// 1. 刷新/关闭/跳转保护
window.addEventListener('beforeunload', e => {
  if (hasUnsavedChanges()) {
    e.preventDefault();
    e.returnValue = '';
  }
});

// 2. 后退按钮保护(SPA 常用)
let popped = false;
history.pushState(null, null, location.href);
window.addEventListener('popstate', () => {
  if (hasUnsavedChanges() && !popped) {
    const ok = confirm('有未保存内容,确定返回?');
    if (!ok) {
      history.pushState(null, null, location.href);
    } else {
      popped = true;
      history.back();
    }
  }
});

// 3. 可见性(性能优化)
document.addEventListener('visibilitychange', () => {
  if (document.hidden) {
    pauseVideoOrPolling();
  } else {
    resumeVideoOrPolling();
  }
});

如果你有具体场景(比如 H5 游戏、表单页、直播间、PWA 等),告诉我,我可以给出更针对性的代码。

文章已创建 3890

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部