原生进度条需用js自定义:监听timeupdate事件更新currentseconds变量,用requestanimationframe节流更新dom;拖拽通过mousedown/mousemove计算位置并设置currenttime;buffered可能不连续,需遍历timeranges;时间显示应格式化而非直接math.floor。

原生 <video></video> 的进度条没法直接样式定制,想改颜色、加拖拽反馈、同步显示时间,必须自己造一个——不是靠 CSS 覆盖,而是用 JS 监听事件 + 手动控制播放位置。
怎么监听视频播放进度并更新自定义进度条
核心是监听 timeupdate 事件,它在播放过程中高频触发(约每 250ms 一次),但别直接在里面做 DOM 更新,容易卡顿。实际做法是用 requestAnimationFrame 节流:
video.addEventListener('timeupdate', () => { updateProgress(); });-
updateProgress()内部只更新一个currentSeconds变量,不操作 DOM - 另起一个
requestAnimationFrame循环,读取该变量并更新<input type="range">的value或div的width
这样既保证视觉流畅,又避免频繁重排。
怎么让自定义进度条支持拖拽跳转
不能只靠 <input type="range"> 的 change 事件,它只在鼠标松开时触发,拖动过程无响应。必须监听 input 事件 + 计算鼠标位置:
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
- 给进度条容器绑定
mousedown,记录初始offsetX和当前video.duration - 拖动中监听
mousemove,用event.clientX - container.getBoundingClientRect().left算出相对位置 - 把位置比例换算成秒数:
video.currentTime = (x / container.offsetWidth) * video.duration - 记得加
video.pause()防止拖动时自动播放干扰定位
漏掉 mouseup 和 mouseleave 清理监听,会导致后续点击失效。
为什么 video.buffered 返回的不是连续区间
浏览器按分片(segment)缓存视频,video.buffered 是个 TimeRanges 对象,可能返回多个不连续区间,比如 [0, 12.5) 和 [23.1, 48.7)。直接取 buffered.end(0) 会漏掉中间已缓存的部分。
- 要用循环遍历:
for (let i = 0; i - 常见需求是画“已缓冲”灰色区域,得合并所有区间再映射到进度条宽度
- 注意
buffered在加载初期可能为空,需加if (video.buffered.length > 0)判断 - 部分移动端浏览器(如 iOS Safari)对
buffered支持不稳定,建议 fallback 到固定“加载中”状态
怎么同步显示当前时间和总时长(如 02:15 / 05:43)
别用 Math.floor(video.currentTime) 直接转整数秒——它会丢掉毫秒,导致时间跳变。正确做法是格式化函数里保留两位小数再截断:
function formatTime(seconds) {
const mins = Math.floor(seconds / 60);
const secs = Math.floor(seconds % 60);
return `${mins}:${secs
- 调用时机:在
timeupdate触发后更新,但同样建议节流(和进度条更新共用同一个requestAnimationFrame) - 总时长
video.duration初始为NaN,要等loadedmetadata事件后才可用 - 如果视频是流式(HLS/DASH),
duration可能为Inf,此时应显示“直播中”而非数字
最易被忽略的是移动端 touch 事件坐标计算和 buffered 的多段处理——这两处不细调,进度条看起来就“不跟手”或“缓冲条断断续续”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










