video 和 audio 元素的 play() 与 pause() 方法需在用户手势触发、媒体加载完成(canplaythrough)后调用,移动端须加 muted 才能自动播放,且 audioContext.resume() 不能替代 play()。
HTML5 的 <video> 和 <audio> 元素原生支持 play() 和 pause() 方法,不需要额外库。调用前必须确保元素已加载完成,否则会抛出 DOMException: The element has no supported sources 或静音策略错误。
常见错误现象:点击按钮没反应,控制台报 NotAllowedError: play() failed because the user didn't interact with the document first —— 这是浏览器自动播放策略限制,必须由用户手势(如 click、touchstart)触发播放。
</body> 前button.addEventListener('click', () => video.play())
play() 可以不依赖手势(但页面刷新后重置)muted 属性才能自动播放带声音的视频视频/音频资源加载状态不确定,过早调用 play() 可能失败。比起监听 loadeddata,canplaythrough 表示媒体已缓冲到可连续播放的程度,更适合做控制入口。
使用场景:需要在页面初始化时预加载并准备播放控制(比如自定义播放器 UI),而不是等用户点“播放”才开始加载。
立即学习“Java免费学习笔记(深入)”;
video.addEventListener('canplaythrough', () => { /* 此时可安全调用 play/pause */ })muted 和 autoplay 属性:<video muted autoplay>
onload 或 readyState === 4 判断——readyState 是同步属性,不能反映网络缓冲情况pause() 不会重置 currentTime,但会把 paused 属性设为 true。很多逻辑错误源于混淆这两个值:比如误以为 paused === false 就代表正在播放(其实可能是加载中、卡住或 ended)。
性能影响:频繁读取 currentTime(如每 50ms)对动画帧率无明显影响,但没必要;监听 timeupdate 更高效。
!video.paused && !video.ended && video.readyState >= 2
currentTime,它本来就不变play() 失败,大概率是被静音策略拦截了,检查是否缺失用户手势上下文当用 AudioContext 控制音频(比如通过 MediaElementAudioSourceNode 接入 <audio>),容易误以为调用 audioContext.resume() 就等于播放媒体元素。其实它只恢复音频上下文,不触发 <audio> 自身的播放流程。
兼容性影响:Safari 对 AudioContext 的自动挂起更激进,即使有用户手势,也可能需要显式 resume() 才能让音频输出生效。
audio.play() 成功(返回 Promise),再在 then 里调用 audioContext.resume()
audioContext.state 为 suspended 时,所有音频节点静音,但 <audio> 的 play() 仍可能成功(只是听不见)audio 元素上监听 play 事件来触发 resume() —— 它可能在 resume() 前就触发了实际中最容易被忽略的是:同一段 JS 逻辑在桌面 Chrome 里跑通,换到 iOS Safari 就静音失败,不是代码问题,而是 muted 属性漏加、或 play() 没包在用户事件里。