video字幕自动启用以document.documentElement.lang为匹配依据,需在loadedmetadata后遍历textTracks;srclang须严格匹配lang前缀,大小写与格式须符合BCP 47,动态切语言需手动重匹配。

lang属性决定video字幕自动启用的依据
浏览器在video加载元数据后,会用document.documentElement.lang作为默认匹配源语言的起点——不是用户系统语言,也不是navigator.language,更不是。如果没写对,textTracks里哪怕有srclang="zh"的轨道,也不会被自动设为showing。
- 必须等
loadedmetadata事件触发后才能遍历textTracks,此时轨道才可用;canplay或canplaythrough太早,textTracks可能为空 -
srclang值必须与document.documentElement.lang严格匹配前缀:比如lang="zh-CN"能匹配srclang="zh"或srclang="zh-CN",但不匹配srclang="zh-china"(非法) - 多个候选轨道时,优先选
srclang完全相等的;无完全匹配则 fallback 到语言码前缀匹配(如zh匹配zh-CN) - 别依赖
default属性:<track default>仅在无document.documentElement.lang或匹配失败时兜底,且 Chrome 120+ 已开始弱化其优先级
lang写错导致字幕“有轨无声”的典型现象
常见报错不是控制台抛异常,而是静默失效:字幕轨道存在、mode初始为disabled、右键菜单里字幕项灰掉。根本原因往往是上lang值非法或未设置:
-
→ 下划线格式被忽略,等价于没写,浏览器当未知语言处理 -
→ 大写不符合BCP 47,部分旧版Safari直接跳过匹配逻辑 -
或→ 视为“语言未声明”,字幕匹配退化为navigator.languages[0],但该值不可靠(可能为en-US) -
→ 对字幕选择完全无效,只影响:lang()CSS和局部断词
动态切换语言时字幕不更新的修复要点
单页应用中改完document.documentElement.lang,已有video元素不会自动重选字幕——它只在loadedmetadata阶段做一次判断。必须手动触发重匹配:
- 监听语言切换事件后,对每个
video重新执行字幕匹配逻辑(即再次调用find(track => track.srclang === ...)) - 不要只设
targetTrack.mode = "showing",必须同步把其他同kind="subtitles"轨道设为"disabled",否则多轨道并存会冲突 - 若视频已播放中,需先
video.pause()再video.load()强制重载元数据(代价高,慎用);更轻量的做法是直接操作textTracks并刷新mode - 注意
textTracks是实时集合,每次访问都需Array.from()转数组,避免迭代时被动态修改导致漏项
嵌入外文字幕时lang与srclang的协同规则
track标签的srclang只声明轨道内容语言,而页面lang决定“谁来听”。二者不一致是常态,但必须语义对齐:
立即学习“前端免费学习笔记(深入)”;
-
<track kind="subtitles" srclang="ja-JP" label="日语">+<html lang="zh-CN">→ 合理:中文主站配日语字幕 -
<track kind="subtitles" srclang="en">+<html lang="en-GB">→ 合理:英式英语主站配通用英语字幕 -
<track kind="subtitles" srclang="fr-FR">+<html lang="fr-CA">→ 慎用:法语变体差异大,Chrome 可能不触发自动启用(建议显式指定srclang="fr"扩大匹配面) - 禁止
srclang="zh"配<html lang="en-US">却不加label——屏幕阅读器无法告知用户该轨道是中文,用户右键菜单里只看到“字幕”二字
document.documentElement.lang,改错一处,全链路失准。



















