浏览器原生不支持自动高亮当前台词,需通过video.textTracks[n].activeCues配合oncuechange事件获取当前字幕,并用JS动态渲染或覆盖层实现高亮。

track 元素本身不支持高亮当前台词
浏览器原生 <track></track> 只负责加载和暴露字幕轨道,渲染样式(包括高亮)完全由 CSS 控制,且仅限于 ::cue 伪元素。它不会自动标记“当前正在播放的那条台词”,也不会把 active cue 单独加 class 或触发 DOM 事件。
用 video.textTracks + cues + oncuechange 捕获当前台词
真正能定位“当前台词”的是 TextTrack 对象的 activeCues 列表,配合 oncuechange 事件监听:
-
video.textTracks[n].mode = "showing"启用轨道后,浏览器才会触发oncuechange - 每次时间轴跨过某条 cue 的起止时间,
video.textTracks[n].activeCues就会更新(通常长度为 0 或 1) - 注意:Chrome/Firefox 行为略有差异——Firefox 可能在 cue 刚开始时就触发,Chrome 偶尔延迟一帧,需容错判断
cue.startTime
手动高亮需要注入 DOM 或操作 ::cue 样式
纯 CSS 无法区分“当前 cue”和“其他 cue”,因为 ::cue 是批量作用于所有显示中的字幕行,没有 :current 或类似选择器。所以必须用 JS 动态控制:
- 方案一(推荐):用
document.createElement("div")在视频上方绝对定位一个覆盖层,把activeCues[0]?.text渲染进去,并加自定义 class 控制高亮背景/边框/字体加粗 - 方案二(局限):通过
video.textTracks[n].cues遍历所有 cue,用cue.line或cue.position等属性做粗略位置映射,再用cue.element(如果已创建)加 class ——但该属性在多数浏览器中为 null,不可靠 - 不要试图改写
::cue的 color 或 background 来“高亮”,它对所有 cue 一视同仁,无法动态响应单条变化
容易被忽略的兼容性坑
看似简单的一句 video.textTracks[0].oncuechange = handler,实际踩点密集:
立即学习“前端免费学习笔记(深入)”;
-
textTracks列表只在<track src="..."></track>加载完成并解析成功后才填充,初始 length 可能为 0;需监听load事件或轮询readyState === TextTrack.LOADED - Safari 对
oncuechange触发时机最保守,有时 cue 已显示但事件未触发,建议 fallback 到requestAnimationFrame+video.currentTime扫描匹配 -
activeCues是实时 live list,但修改它的text或startTime不会反向影响渲染——它是只读快照 - 如果字幕来自 HLS/DASH 流(非外挂 .vtt),
textTracks必须由 hls.js/dash.js 手动addTextTrack()注入,原生<track></track>标签完全无效



















