default属性不可靠,仅在极少数干净环境下可能使字幕轨道mode初始为"showing";真要默认显示必须用JavaScript在loadedmetadata后主动设track.mode="showing"。

default 属性根本不能可靠设“默认显示”,它只在极少数干净环境下可能让字幕轨道初始 mode 为 "showing",但用户一点击字幕开关、刷新页面、换浏览器或用 Safari,就失效。真想字幕一上来就可见,必须用 JS 主动设 track.mode = "showing"。
为什么写了 default 字幕还是不显示
这不是代码写错了,而是浏览器压根没按你预期执行:
-
default不等于“自动渲染”,只表示“可被默认启用”——是否真启用,取决于用户历史操作、浏览器策略和加载时机 - Chrome 可能在首次访问且用户从未点过 CC 按钮时生效;Firefox 常忽略它,
mode初始仍是"disabled" - iOS Safari(包括 iOS 16.3 及更早)完全不响应
default,textTracks[i].mode永远是"disabled" - 只要用户之前手动关闭过字幕,
default就永久失效,哪怕你清空缓存也恢复不了 -
srclang="zh-CN"和系统语言navigator.language === "zh"不匹配,也会导致轨道不被选中
default 的合法用法与硬性限制
如果非要加 default,得同时满足所有条件,缺一不可:
- 只能用在一个
<track>上,多个default会导致行为未定义(多数浏览器只认第一个,其余静默丢弃) -
kind必须是"subtitles"或"captions",写成"subtitle"或带空格的"subtitles "会被浏览器直接忽略 -
srclang必须是合法 BCP 47 码(如"zh"、"en-US"),不能是"chinese"或空字符串 -
<track>必须紧跟在<source>后、且嵌套在<video>内,放错位置(比如包在<div>里)就无效 - VTT 文件必须返回 HTTP 200 + MIME 类型
text/vtt;本地双击 HTML 打开时file://协议会直接拒绝加载,无任何报错
真正可控的默认启用方式:JS 主动设 mode
别依赖 default,监听 loadedmetadata 后手动匹配并启用:
立即学习“前端免费学习笔记(深入)”;
video.addEventListener('loadedmetadata', () => {
const userLang = navigator.languages?.[0] || navigator.language;
const targetTrack = Array.from(video.textTracks).find(track =>
track.kind === 'subtitles' &&
(track.srclang === userLang || track.srclang.startsWith(userLang.split('-')[0]))
);
if (targetTrack && targetTrack.readyState === 2) {
targetTrack.mode = 'showing';
}
});
- 必须等
loadedmetadata(不是DOMContentLoaded),否则textTracks可能为空或未就绪 - 检查
track.readyState === 2(LOADED),避免 VTT 加载失败时强行设mode - 优先匹配完整语言码(如
"zh-Hans"),再 fallback 到主语言(如"zh") - 别忘了关掉其他同 kind 轨道:
otherTrack.mode = "disabled",否则可能多条字幕同时出现
最常被忽略的点:VTT 文件加载失败时浏览器静默失败,控制台不报错也不触发 error 事件。上线前务必用 Network 面板确认 .vtt 返回 200 且 MIME 正确——这是比 default 更底层、更致命的卡点。



















