直接修改track.src无效,需先remove再重建;mode属性可实时开关字幕;切换时须手动处理default属性;无load()方法,重建或WebVTT API是替代方案。

直接改 track 元素的 src 属性没用,得先移除再重建
浏览器对已加载的 <track></track> 元素限制很死——哪怕你用 element.src = 'new.vtt' 或 element.setAttribute('src', 'new.vtt'),视频播放器也不会重新加载字幕。这是因为规范要求 track 的 src 只在插入 DOM 时被解析一次。
实操建议:
- 先用
track.remove()把旧<track></track>从<video></video>中彻底移除 - 创建新
HTMLTrackElement:const newTrack = document.createElement('track') - 按需设置属性:
newTrack.kind = 'subtitles'、newTrack.src = 'zh-CN.vtt'、newTrack.srclang = 'zh'、newTrack.label = '中文' - 用
video.appendChild(newTrack)插入,此时浏览器才会发起请求并加载
track.mode 是唯一能实时生效的属性
如果你只是想开关字幕显示(不换文件),直接操作 mode 就行,它不需要重建元素。
常见取值和效果:
立即学习“前端免费学习笔记(深入)”;
-
track.mode = 'disabled':隐藏字幕,也不触发加载 -
track.mode = 'hidden':字幕不显示,但仍在后台解析(用于搜索) -
track.mode = 'showing':显示字幕(等效于用户点击字幕按钮)
注意:mode 改变后,track 的 readyState 必须 ≥ 2(LOADED)才有效;如果还是 0(NOT_LOADED),说明 src 没加载完,强行设 showing 会静默失败。
动态切换字幕时,别漏掉 default 属性的互斥处理
多个 <track></track> 同时存在时,只有带 default 属性的那个会在视频加载时自动启用(mode = 'showing')。但 DOM 中的 default 是静态属性,不会自动取消其他 track 的默认状态。
所以切换主字幕要手动清理:
- 先遍历所有同级
track,把它们的default属性全移除:track.removeAttribute('default') - 再给目标
track设上:targetTrack.setAttribute('default', '') - 最后设
targetTrack.mode = 'showing'
否则可能出现两个字幕同时显示,或新字幕不自动激活的问题。
用 load() 方法强制重载字幕内容?不行,这个方法不存在
有人看到 HTMLMediaElement 有 load(),就以为 HTMLTrackElement 也有——但它真没有。查 MDN 或调用 typeof track.load 都会返回 'undefined'。
替代方案只有两个:
- 重建
track元素(最可靠) - 如果只是更新字幕文本(比如翻译后热替换),可考虑用 WebVTT API 解析内容,再通过
VTTCue+TextTrackCueList手动注入(适合高级控制,但复杂度高)
真正容易被忽略的是:重建 track 后,textTracks 列表索引会变,之前存的 video.textTracks[0] 可能指向错误轨道。建议始终用 Array.from(video.textTracks).find(t => t.srclang === 'zh') 这类方式定位,而不是硬编码索引。



















