监听页面可见性变化并暂停音视频是最稳定方案:监听document的visibilitychange事件,检查document.hidden,对readyState>1的audio/video元素调用pause()。

页面切到后台(比如切换标签页、最小化窗口、锁屏)时,HTML5 的 <audio> 和 <video> 默认不会自动暂停——这是浏览器的正常行为,但会持续耗电、占音频通道,还可能干扰用户。最稳定可靠的解决方式是监听 visibilitychange 事件。
用 visibilitychange 监听页面可见性变化
这是 HTML5 原生标准事件,兼容所有主流浏览器(包括 iOS Safari),比 blur 或 focus 更准确,能覆盖标签页切换、锁屏、弹窗遮挡等多种不可见场景。
- 监听必须注册在
document上,确保全局生效,尤其适合动态插入的音视频元素 - 事件只通知“状态变了”,不带当前值,所以每次触发都要检查
document.hidden -
document.hidden === true表示页面已不可见,此时应暂停媒体
暂停前检查媒体就绪状态
直接调用 pause() 可能失败,尤其是媒体还没加载完成或网络中断时。需先判断是否具备暂停条件:
- 用
audio.readyState > 1(即HAVE_CURRENT_DATA或更高)确保已有可播放数据 - 避免对
networkState === 0(NETWORK_EMPTY)的元素调用pause(),它还没开始加载 - 推荐写法:
if (el.readyState > 1) el.pause();
统一控制所有音视频元素
不要靠 class 名、id 列表或 jQuery 选择器,容易遗漏或维护困难。直接使用原生 API 批量操作:
立即学习“前端免费学习笔记(深入)”;
-
document.querySelectorAll('audio, video')一次性获取全部媒体元素 - 遍历 NodeList 并逐个检查和暂停:
els.forEach(el => { if (el.readyState > 1) el.pause(); }); - 无需区分 audio 还是 video,逻辑完全一致
补充:避免常见坑
iOS Safari 对媒体控制极严格,即使加了 muted,若首次播放没经用户手势(如点击),readyState 可能长期为 0,导致后续 pause() 无效。因此:
- 首次播放必须由真实用户交互触发(不能靠
load或setTimeout) - 不要用
volume = 0替代muted,前者不是真正的静音开关,部分设备仍会输出无声信号 - 如果页面用单页路由(如 shiny.router),还需额外监听
hashchange或popstate,因为visibilitychange不覆盖路由内跳转



















