不能,离开页面时audio.play()不会在后台继续运行,浏览器会强制暂停;必须通过pagehide和visibilitychange事件主动调用pause()并重置currenttime,且unload事件已不可靠。

离开页面时 audio.play() 还在后台跑?浏览器根本不管
现代浏览器(Chrome、Safari、Edge)**不会自动暂停或停止**已播放的 <audio></audio> 元素,即使用户切走标签页、最小化窗口或关闭页面——除非你主动干预。更关键的是:beforeunload 和 pagehide 事件里调用 pause() 或 load() 是唯一可行路径,但有严格限制:不能触发新音频加载,也不能依赖异步操作。
用 pagehide 比 beforeunload 更可靠
pagehide 是目前最稳的选择,它在页面被隐藏(含后台、切换标签、安卓 Chrome 多任务)时触发,且兼容 iOS Safari;beforeunload 在部分安卓 WebView 和新版 Safari 中已被弱化,且可能被阻止执行 JS。
- 必须监听
window,不是document或audio元素本身 - 不要在回调里调用
play()或修改src,只做pause()或currentTime = 0 - 如果音频是循环播放(
loop = true),仅pause()不够,建议加currentTime = 0避免恢复时跳帧
示例:
const audio = document.getElementById('bgm');
window.addEventListener('pagehide', () => {
if (!audio.paused) {
audio.pause();
audio.currentTime = 0;
}
});
移动端 iOS Safari 的隐藏坑:pagehide 可能不触发
iOS Safari 在 App 切换或锁屏时,pagehide 有时会延迟甚至丢失。此时需叠加 visibilitychange 监听,并检查 document.hidden 状态:
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
- 当
document.hidden === true且音频正在播放,立即pause() - 不要依赖
visibilitychange单独使用——它在页面首次加载时也可能触发 false 正面 - 两个事件都注册,互为兜底,但避免重复暂停(加个标志位或判断
!audio.paused)
补充代码:
let isPausedByVisibility = false;
document.addEventListener('visibilitychange', () => {
if (document.hidden && !audio.paused && !isPausedByVisibility) {
audio.pause();
isPausedByVisibility = true;
}
});
// pagehide 回调里重置标志位
window.addEventListener('pagehide', () => {
isPausedByVisibility = false;
});
为什么 unload 事件里 audio.pause() 常失效
unload 已被多数浏览器弃用,Chrome 从 v114 起完全移除支持,Safari 也仅保留基础行为。更重要的是:unload 回调中禁止执行任何可能阻塞页面卸载的操作,而 audio.pause() 在某些实现中会被视为“潜在耗时”,直接忽略。
- 别写
window.addEventListener('unload', ...)—— 它大概率不执行 - 不要试图在
unload里调用fetch()或发统计日志,同样会被中断 - 如果真需要记录“用户离开了”,改用
beacon API(navigator.sendBeacon()),它专为此类场景设计
真正要做的,就两件事:用 pagehide + visibilitychange 组合保底,所有逻辑控制在同步、无副作用范围内。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










