video元素默认不记忆播放位置,需在pause事件中用localStorage保存currentTime,并在canplay事件后读取恢复;注意iOS Safari静音限制、安卓WebView兼容性及无痕模式异常处理。
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 对自动播放和 currentTime 设置有严格限制:
muted 且无用户手势触发,play() 会失败,进而导致 currentTime 设置无效(即使设置了也跳不回去)canplay 阶段设置 currentTime 会失败,可降级到 loadedmetadata 或加 setTimeout(..., 0) 延迟执行localStorage 在无痕模式下可能抛出 QuotaExceededError,需包裹 try/catch
单纯监听 canplay 不够——如果用户快速刷新,视频可能还没加载完就尝试恢复;或者 currentTime 超出实际时长(比如视频被替换过)。实际部署时应:
video.duration 是否有效(大于 0),再比较 savedTime 是否小于它video.currentTime = x 操作做 try/catch,捕获 InvalidStateError 或 DOMException
真正难的不是写几行代码,而是判断什么时候该设、什么时候不该设、设了但没生效时怎么兜住——这些边界条件,往往只在真实用户反复刷新、切后台、横竖屏切换后才暴露出来。