audio标签默认不支持断点续播,需用localStorage/sessionStorage手动存取currentTime,并在loadedmetadata后设置时间再play(),且play()必须由用户手势触发。

audio 标签默认不支持断点续播,必须手动保存和恢复播放位置
浏览器原生 <audio> 没有内置“记住上次听到哪”的能力。刷新、关闭标签页、甚至页面重渲染后,currentTime 都会重置为 0。要实现断点续播,核心是:在用户离开前存下当前时间,在加载时读取并设置回去。
用 localStorage 存储 currentTime,页面加载后 set currentTime 再 play()
这是最轻量、兼容性最好的方案,适用于单音频文件场景。注意几个关键时机和边界条件:
- 监听
timeupdate事件存时间,但别每帧都写 localStorage(性能差),建议节流到约 5 秒一次 - 必须在
loadedmetadata或canplay后再调用play(),否则 iOS Safari 和部分安卓浏览器会静音拦截 - 恢复时先设
currentTime,再调用play();如果音频未加载完成就设时间,会触发seeking但可能失败 - 示例逻辑:
const audio = document.querySelector('audio'); const key = 'audio_last_time'; audio.addEventListener('loadedmetadata', () => { const saved = localStorage.getItem(key); if (saved && !isNaN(saved)) { audio.currentTime = parseFloat(saved); } }); audio.addEventListener('timeupdate', () => { if (audio.readyState > 0) { localStorage.setItem(key, audio.currentTime.toString()); } }); audio.addEventListener('ended', () => { localStorage.removeItem(key); });
使用 sessionStorage 替代 localStorage 的适用场景
如果只希望“本次会话内”续播(比如用户关掉标签页就清空),用 sessionStorage 更合适:
-
sessionStorage在标签页关闭后自动清除,避免跨会话误续播 - API 完全一致:
sessionStorage.setItem(key, time)/getItem - 适合播客单集、教程视频分段等“一次听完”的内容
- 不适用于需要跨天/跨设备续播的场景(那得上服务端 + 用户登录)
移动端自动播放限制会让 play() 失败,必须由用户手势触发
iOS Safari 和 Chrome Android 对自动播放极其严格:没有用户点击/触摸动作,audio.play() 会直接抛出 NotAllowedError。这意味着:
立即学习“前端免费学习笔记(深入)”;
- 不能在
DOMContentLoaded或load里直接play() - 必须把
play()放在用户可感知的交互回调中,比如按钮onclick、touchstart - 如果想“点一下继续播放”,可先用一个 mute 的
play()解锁媒体上下文,再后续控制音量和时间 —— 但这个 hack 在 iOS 17+ 已基本失效 - 更稳妥的做法:UI 上显示“继续播放”按钮,点击后恢复时间并
play(),同时把按钮逻辑和存储读取绑定在一起
readyState 判断和 iOS 的手势链要求——没等元数据加载完就设 currentTime,或没用户点击就调 play(),都会让续播逻辑静默失败。



















