track不工作首要检查是否被浏览器忽略:必须是video直接子元素、紧贴source后、属性kind/srclang/label/src四者齐全且格式严格,VTT首行须为顶格大写WEBVTT,服务端返回text/vtt类型。

track 元素不工作,先看它是不是被浏览器“当没看见”
绝大多数 track 失效,不是代码写得不够多,而是浏览器压根没解析到——它对位置、结构、属性三者零容忍。常见现象:右键字幕菜单空着、video.textTracks.length 恒为 0、Network 面板里根本没发请求。
-
track必须是的**直接子元素**,且必须紧贴在所有标签之后、之前;写在里、外、或两个中间,等于没写- 不能用 JS 动态
appendChild插入已加载完成的—— 浏览器只在初始 HTML 解析阶段扫描track- 多个
track并列时,中间插了 HTML 注释或空行,Safari 可能中断后续解析必须带controls属性(尤其移动端 Safari),否则字幕菜单根本不出现四个属性缺一不可:
kind、srclang、label、src浏览器不做任何推断,漏一个,该轨道就进不了右键菜单,连报错都不会有。
-
kind="subtitles":必须全小写、拼写完整;kind="caption"、kind="subtitles "(末尾空格)或留空,全部失效 -
srclang:必须是合法 BCP 47 码,如zh-Hans、en-US、ja;chinese、zh_CN、cn全部被忽略 -
label:用户看到的菜单名,为空时显示(no label),多语言场景下无法区分,建议写成label="中文(简体)" -
src:路径需可访问;若跨域,服务端必须返回Access-Control-Allow-Origin: *,否则 Firefox/Edge 静默失败
VTT 文件和服务器响应是静默杀手
即使 HTML 结构和属性全对,VTT 文件或服务端配置错一位,字幕照样不显示,而且控制台几乎不报错。
- VTT 首行必须顶格、全大写、无空格、无 BOM、无注释:
WEBVTT—— 写成webvtt、WEBVTT(带空格)、或带 UTF-8 BOM(Windows 记事本默认),整个文件被丢弃 - 时间戳毫秒位必须三位,如
00:00:01.230 --> 00:00:04.567;写成.23或.2300都会解析失败 - 服务端必须返回
Content-Type: text/vtt;返回text/plain或application/octet-stream,Chrome 直接忽略 - 本地开发别用
file://协议双击打开 —— 所有src请求被拦截,必须起本地服务(如python3 -m http.server)
default 属性基本靠不住,要用 JS 主动控制
default不是“默认开启”,只是个弱信号,实际生效条件苛刻到几乎不可控。- 多个
track都写了default→ 多数浏览器直接忽略全部 - 用户只要点过一次字幕开关(哪怕只是打开又关闭),
default就永久失效 - Safari 私密模式下可能跳过解析
track节点,default彻底无效 - 真正可靠的做法是监听
loadedmetadata后手动设mode = "showing":video.addEventListener('loadedmetadata', () => { const targetTrack = Array.from(video.textTracks).find(t => t.kind === 'subtitles' && t.srclang === 'zh' ); if (targetTrack) targetTrack.mode = 'showing'; });
最常被忽略的一点:VTT 文件首行
WEBVTT是否真的“干净”——没有不可见字符、没有缩进、没有 BOM。这个细节出错,整条轨道就废了,但你根本看不到任何提示。 - 不能用 JS 动态
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











