HTML字幕的default属性仅是一次性提示且浏览器通常忽略,真正生效需JS监听loadedmetadata后主动匹配语言并设mode="showing"。

HTML 字幕(<track></track>)没有“恢复默认值”机制,default 属性不是开关,也不是可重置的状态;它只是一次性提示,且浏览器几乎从不按你预期执行。
为什么 default 设了也不显示字幕
这不是代码写错了,是浏览器根本没打算照做。常见失效链路如下:
-
<track></track>的srclang和navigator.languages[0]不匹配(比如写了zh-CN,但系统返回zh-Hans或zh) - 多个
<track default></track>同时存在 → 大部分浏览器直接忽略全部 -
kind不是"subtitles"(例如用了"captions"或"descriptions") -
src返回 404、CORS 错误,或服务端没返回Content-Type: text/vtt - 视频还没触发
loadedmetadata事件,video.textTracks还是空数组
textTracks 是动态集合,必须等 loadedmetadata 后才能操作
DOM 加载完成 ≠ 字幕轨道就绪。video.textTracks 在视频元数据加载前为空,此时遍历会得到空数组,设 mode 也无效。
- 监听
loadedmetadata,不是DOMContentLoaded或load - 用
Array.from(video.textTracks)转成真数组再遍历(避免 live HTMLCollection 副作用) -
track.mode只接受三个字符串:"disabled"、"hidden"、"showing";设错值会被静默忽略 - 别忘了关掉其他同 kind 的轨道,否则可能多轨并存、样式打架
真正可控的“恢复默认字幕”逻辑
靠 JS 主动匹配 + 强制启用,绕过 default 的所有不确定性:
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
立即学习“前端免费学习笔记(深入)”;
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');
}
});
注意:如果用户手动切换过字幕,这个逻辑仍会覆盖——这才是“恢复默认”的实际含义:丢弃用户临时选择,回到语言偏好驱动的初始状态。
移动端 Safari 是最大变量
iOS 16.3 及更早版本中,<track default></track> 几乎完全被跳过,连 DOM 解析都可能省略。即使加了 JS 匹配,也要确认:
- 是否在私密模式下(Safari 私密模式会禁用
<track></track>解析) -
video.src是否已设置且合法(未设置 src 时,loadedmetadata永远不会触发) -
<track></track>标签是否写在<video></video>内部(外部插入无效)
最易被忽略的一点:字幕文件本身必须是 UTF-8 编码,BOM 头会导致解析失败,mode = "showing" 也白设。


















