default属性不可靠,必须用JavaScript在loadedmetadata后设textTrack.mode为showing;常见失效原因包括srclang不匹配、多个default、kind非subtitles、src错误、HTML结构不规范及.vtt文件格式/编码问题。

default 属性不能可靠让字幕默认显示,它只在极少数初始场景下“可能生效”,绝大多数实际项目中必须用 JavaScript 主动控制 mode。
为什么加了 default 却没显示字幕
这不是你漏写了属性,而是浏览器根本没执行“默认开启”这个动作。常见失效原因包括:
-
srclang值不匹配用户系统语言(比如写zh-CN,但navigator.language返回zh;或拼成chinese) - 多个
<track></track>都写了default→ 大部分浏览器直接忽略全部,行为未定义 -
kind不是"subtitles"(例如用了"captions"或漏写s写成"subtitle") -
src指向的 .vtt 文件返回 404、CORS 错误,或服务端没返回Content-Type: text/vtt - 视频还没触发
loadedmetadata事件,video.textTracks还是空数组,default根本没机会被处理
HTML 结构和属性必须全对,否则 track 不进菜单
浏览器对 <track></track> 的识别极其严格,缺一环就静默失败:
-
<track></track>必须是<video></video>的**直接子元素**,且**紧接在所有<source></source>之后、之前** - 四个属性缺一不可:
kind="subtitles"、src="zh.vtt"、srclang="zh"、label="中文" -
.vtt文件首行必须是顶格大写的WEBVTT,后面空一行;时间戳格式为00:00:01.234 --> 00:00:04.567(毫秒三位,箭头前后两个空格) - 文件编码必须是 UTF-8 无 BOM;本地开发时不能用
file://协议,得起本地服务(如python3 -m http.server)
用 JavaScript 主动设 mode 才真正可控
监听 loadedmetadata 后遍历 textTracks,手动匹配并启用目标轨道:
立即学习“前端免费学习笔记(深入)”;
video.addEventListener('loadedmetadata', () => {
const lang = navigator.languages?.[0] || document.documentElement.lang || 'zh';
const targetTrack = Array.from(video.textTracks).find(track =>
track.kind === 'subtitles' &&
(track.srclang === lang || track.srclang.startsWith(lang.split('-')[0]))
);
if (targetTrack) {
targetTrack.mode = 'showing';
Array.from(video.textTracks)
.filter(t => t !== targetTrack && t.kind === 'subtitles')
.forEach(t => t.mode = 'disabled');
}
});
注意:textTracks 是动态集合,必须等 loadedmetadata 触发后才能读取;mode 只能设为 "disabled"、"hidden" 或 "showing";不要在 DOMContentLoaded 或插入 DOM 后立刻操作,那时轨道大概率还没加载。
真正容易被忽略的是:即使结构、路径、格式全对,default 依然可能不生效——因为它的逻辑只服务于“首次访问 + 未操作过字幕开关 + 浏览器恰好支持”这个狭窄窗口。生产环境别赌这个概率。



















