video元素默认不记忆播放位置,需在pause事件中用localStorage保存currentTime,并在canplay事件后读取恢复;注意iOS Safari静音限制、安卓WebView兼容性及无痕模式异常处理。

video 元素默认不记忆播放位置,需手动保存 currentTime
HTML5 的 元素本身不会自动记住用户暂停时的位置。每次刷新或重新加载页面,currentTime 都会重置为 0。关键在于:你必须在暂停(pause)事件中主动读取并持久化当前时间点,再在播放前(如 loadstart 或 canplay)恢复它。
用 localStorage 存储和恢复 currentTime 最实用
相比 sessionStorage(关闭标签页即丢失)或后端存储(过度设计),localStorage 是轻量、跨刷新、无需服务端配合的首选。注意以下实操要点:
-
localStorage只支持字符串,必须用JSON.stringify()或直接.toString()存,用parseFloat()读,避免恢复成NaN - 建议以视频
src为 key,防止多个视频互相覆盖,例如:localStorage.setItem('video_resume_' + video.src, video.currentTime.toString()) - 恢复时机选在
canplay事件后更稳妥,此时媒体已加载元数据且可安全设置currentTime - 设置
currentTime后应调用video.play().catch()避免因策略限制被静音拦截
const video = document.querySelector('video');
const key = 'video_resume_' + video.src;
video.addEventListener('pause', () => {
localStorage.setItem(key, video.currentTime.toString());
});
video.addEventListener('canplay', () => {
const savedTime = parseFloat(localStorage.getItem(key));
if (!isNaN(savedTime) && savedTime > 0) {
video.currentTime = savedTime;
}
});
// 可选:页面卸载前再存一次,防意外中断
window.addEventListener('beforeunload', () => {
localStorage.setItem(key, video.currentTime.toString());
});
注意 iOS Safari 和部分安卓 WebView 的兼容性坑
iOS Safari 对自动播放和 currentTime 设置有严格限制:
- 若视频未设置
muted且无用户手势触发,play()会失败,进而导致currentTime设置无效(即使设置了也跳不回去) - 某些安卓 WebView 在
canplay阶段设置currentTime会失败,可降级到loadedmetadata或加setTimeout(..., 0)延迟执行 -
localStorage在无痕模式下可能抛出QuotaExceededError,需包裹try/catch
更健壮的恢复逻辑要处理加载状态与错误边界
单纯监听 canplay 不够——如果用户快速刷新,视频可能还没加载完就尝试恢复;或者 currentTime 超出实际时长(比如视频被替换过)。实际部署时应:
立即学习“前端免费学习笔记(深入)”;
- 检查
video.duration是否有效(大于 0),再比较savedTime是否小于它 - 对
video.currentTime = x操作做try/catch,捕获InvalidStateError或DOMException - 考虑添加一个“跳转失败”的 fallback 提示,比如显示按钮让用户手动点击恢复
真正难的不是写几行代码,而是判断什么时候该设、什么时候不该设、设了但没生效时怎么兜住——这些边界条件,往往只在真实用户反复刷新、切后台、横竖屏切换后才暴露出来。











