play() 调用后需监听 playing 事件确认真正播放再暂停,pause() 安全可重调,play() 必须处理 Promise reject,暂停前应缓存 currentTime 并在继续前恢复。

play() 调用后无法暂停?先确认是否真在播放中
浏览器里 play() 不是“按下就播”,它可能静默失败,尤其在用户无交互(如点击)后自动调用时。此时 audio.paused 仍是 true,audio.playing 不存在,直接调 pause() 没效果,还可能抛 DOMException: The element has no supported sources 或静默忽略。
- 务必在
play()后监听playing事件,确认真正进入播放状态再允许暂停操作 - 避免在页面加载完成时立即调
play();改用用户点击、触摸等交互事件触发 - 检查
audio.src是否已设置且可访问,空 src 或 404 会导致play()返回 Promise 并 reject
暂停/继续必须用 pause() 和 play(),没有 toggle 方法
HTMLMediaElement 没有内置的 togglePlay(),也不能靠 audio.muted = !audio.muted 伪装控制。暂停和继续是两个独立动作,状态判断必须依赖 paused 属性,而不是靠变量标记。
- 暂停:直接调
audio.pause(),无需条件判断;即使已暂停,多次调用也安全 - 继续:必须用
audio.play(),且它返回 Promise;需处理 reject,否则后续逻辑可能卡住 - 错误写法:
if (audio.paused) audio.play(); else audio.pause();—— 看似合理,但play()失败时paused仍为true,下次点“继续”又会重试失败
play() 继续播放时常见 Promise 错误及应对
play() 在非用户手势上下文或音频被系统中断(如来电、其他音频抢占)后恢复时,大概率 reject,错误信息通常是 "The request is not allowed by the user agent or the platform in the current context." 或 "play() failed because the user didn't interact with the document first."
- 必须用
.catch()捕获失败,不要只写.then() - 失败后别静默,建议 UI 提示“请点屏幕任意位置再试”,并重新绑定一次点击事件监听
- 部分安卓 WebView 或 iOS Safari 对后台播放限制更严,即使用户点过,切到后台再切回也可能需再次交互才能恢复
audio.currentTime 可能跳变,暂停前最好缓存位置
暂停本身不改变 currentTime,但如果你在暂停后手动修改了 src 或触发了 reload,currentTime 会重置为 0。更隐蔽的问题是:某些低版本 Android 浏览器在 pause() 后读 currentTime 会滞后几毫秒,导致“继续”时听起来像卡了一下。
- 推荐在调
pause()前主动记录:const lastTime = audio.currentTime; - 继续前先设回:
audio.currentTime = lastTime;,再调play() - 避免在
timeupdate事件里频繁读写currentTime,尤其在低端设备上可能引发抖动
currentTime 的精度、跨平台行为差异,每个点都可能单独出问题。最常被忽略的是:把 play() 当同步函数用,不处理它的异步失败。










