video元素的currentTime属性是核心控制点,以秒为单位可读可写,但需检查readyState≥2、限制跳转范围,并注意iOS Safari等平台需用户手势触发首次播放才能可靠设置。
currentTime 属性是核心控制点HTML5 元素本身不提供原生快进/后退按钮,所有进度跳转都依赖 JavaScript 操作 currentTime。这个属性以秒为单位,可读可写,直接赋值就能跳转——但要注意它不是实时同步的,尤其在缓冲不足或格式不支持时可能被忽略或延迟生效。
常见错误:直接写 video.currentTime += 10 却没检查边界,导致跳到负数或超出时长,引发静音、卡顿甚至 InvalidStateError。
video.duration 是否已加载(video.readyState >= 2),否则 duration 可能为 NaN
Math.max(0, Math.min(video.duration, video.currentTime + offset))
currentTime 跳转可能触发重新请求分片,延迟比本地 MP4 高得多用固定偏移量做快进后退最常用,但必须结合播放状态和加载状态判断。不能只靠 click 事件,要防连续点击、暂停中跳转失败等场景。
const video = document.querySelector('video');
const seekForward = () => {
if (video.readyState < 2) return;
const newPos = Math.min(video.duration, video.currentTime + 15);
video.currentTime = newPos;
};
const seekBackward = () => {
if (video.readyState < 2) ret
urn;
const newPos = Math.max(0, video.currentTime - 5);
video.currentTime = newPos;
};
document.getElementById('forward-btn').addEventListener('click', seekForward);
document.getElementById('backward-btn').addEventListener('click', seekBackward);
注意:video.readyState === 0 表示尚未加载元数据;=== 1 表示有元数据但无帧;≥ 2 才能安全读取 duration 和设置 currentTime。
timeupdate 时别直接修改 currentTime
很多教程在 timeupdate 回调里做自动跳过广告或章节,但这里改 currentTime 容易引发循环:跳转 → 触发 timeupdate → 再跳转 → 卡死或报错 InvalidStateError: The element has no supported sources。
timeupdate 中无条件赋值 currentTime
if (!isJumping) { isJumping = true; video.currentTime = target; setTimeout(() => isJumping = false, 100); }
seeking 和 seeked 事件,仅在 seeked 后再执行后续逻辑iOS Safari 对 currentTime 设置极其保守:未播放过的视频、preload="none"、或用户未触发过播放手势(如点击)时,直接设 currentTime 会静默失败,且不抛错。
绕过方法只有两个:
play()(哪怕只播 1ms 然后 pause()),之后才能自由跳转video.load() + video.play().catch(e => console.log(e)) 强制加载元数据,但部分 iOS 版本仍会拒绝非手势上下文的 play()
这问题在微信内置浏览器、QQ 浏览器里同样存在,测试时务必真机验证,模拟器常表现正常但实际失效。