default属性无法可靠启用字幕,仅极少数条件下使track.mode初始为"showing",但用户仍需手动开启;常见失效原因包括kind拼写错误、srclang不合法、track位置不当、vtt加载失败、ios safari无视default、多default仅首生效、default不关联语言匹配、用户操作后永久失效;真正可控方式是js监听loadedmetadata后设targettrack.mode="showing"并确保readystate===2且排除同kind其他轨道。

default 属性不能可靠设置默认启用的字幕轨道,它只在极少数前提下可能让 track.mode 初始为 "showing",但用户仍需手动打开字幕开关才能看到文字——这不是 bug,是浏览器规范强制行为。
为什么写了 default 字幕还是不显示
常见失效原因不是你漏写了属性,而是底层条件没满足:
-
kind拼错(比如写成"subtitle"或"subtitles "带空格),Safari 直接跳过整条<track></track> -
srclang不合法:用"chinese"、"zh_CN"、空字符串或大小写混用(如"ZH"),轨道无法注册进video.textTracks -
<track></track>没放在<source></source>之后、之前,浏览器解析时静默忽略 - VTT 文件返回 404、CORS 错误,或服务端没配
Content-Type: text/vtt,加载失败但控制台无提示 - 移动端 Safari(iOS/iPadOS)完全无视
default,track.mode初始恒为"disabled"
default 只能用在一个 <track></track> 上
多个 default 属性不会叠加生效,多数浏览器只取第一个,其余被忽略——该行为未定义,不可依赖:
- 即使你给中英日三语都加了
default,Chrome 也只尝试启用第一个,Firefox 可能全禁用 -
default不代表“优先匹配”,它和srclang、navigator.languages无关,纯属 HTML 静态声明 - 用户只要点过一次播放器上的字幕按钮(哪怕只是打开又关闭),
default就永久失效,刷新页面也不恢复
真正可控的默认启用方式:JS 主动设 track.mode = "showing"
必须等轨道加载完成再操作,否则 video.textTracks 是空数组或未就绪:
- 监听
loadedmetadata事件(比DOMContentLoaded或canplay更稳妥) - 用
navigator.languages[0]或document.documentElement.lang匹配srclang,支持主语言 fallback(如"zh-Hans"→"zh") - 设目标轨道
mode = "showing"前,确认track.readyState === 2(LOADED) - 同时把其他同 kind 轨道设为
"disabled",避免多轨冲突
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';
Array.from(video.textTracks)
.filter(t => t !== targetTrack && t.kind === 'subtitles')
.forEach(t => t.mode = 'disabled');
}
});
最易被忽略的一点:track.mode 是实时状态,而 default 只影响初始值;只要用户点过字幕开关,后续所有逻辑都以 mode 为准——调试时务必清空浏览器字幕偏好设置,否则旧选择会覆盖 JS 设置。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











