必须为每个含文本的语义化标签显式设置lang属性,且严格遵循BCP 47格式;data-i18n仅处理textContent,其他属性需加对应后缀;动态插入DOM需手动触发翻译;语言包须扁平结构、键名一致、带fallback机制。

只改document.documentElement.lang根本没用
这是最常被踩的坑:改完根节点语言,页面文字不变、屏幕阅读器照旧读错、中文顿号按英文间距渲染、<pre class="brush:php;toolbar:false;" lang="bash"></pre>里的代码字体被中文字体覆盖。浏览器和辅助技术不看父级lang,只认每个元素自己的lang属性——它决定标点宽度、连字规则、字体回退链、语音引擎发音方式。
必须显式为所有含文本的语义化标签设置lang:<h1></h1>、<p></p>、<section></section>、<footer></footer>等。已有lang的特殊元素(如<pre class="brush:php;toolbar:false;" lang="bash"></pre>、<code lang="sql">)切换语言时要保留原值,这是多语言混排的合法场景。
- 切换语言时,遍历所有已带
lang属性的元素,同步更新其值(除非明确要保留原语言) -
<script></script>和<style></style>内部设lang无效,它们不参与文本渲染 - 值必须严格符合BCP 47格式:用
zh-Hans,别用zh_CN或chinese;iOS VoiceOver对ja支持差,得写ja-JP
data-i18n标记只管textContent,其他属性得手动加后缀
data-i18n默认只替换元素的textContent,对placeholder、title、alt、aria-label等完全无效。常见错误是写了<input placeholder="Search">,切语言后还是英文;<img alt="user avatar">的替代文本没更新;<label for="email">Email</label>翻了但for属性没同步,点击失效。
必须显式加对应后缀:
data-i18n-placeholder="search_hint"data-i18n-alt="avatar_desc"data-i18n-title="tooltip_info"data-i18n-aria-label="close_button"
value属性一般不翻译(属于用户输入数据),跳过处理;但<button></button>和<input type="submit">的显示文案建议统一用textContent更新,避免value被意外提交。
动态插入的 DOM 不会自动翻译
AJAX加载的弹窗、分页表格新行、懒加载模块插入后,里面的data-i18n标记只是字符串,不会变成对应语言文本。点击按钮打开的<modal></modal>,内部<h2 data-i18n="modal_title"></h2>不会自动更新;分页表格每页获取新<tr>,新行里的<code>data-i18n保持原始键名。
解决方案是插入后立即调用翻译函数,而不是依赖MutationObserver自动监听——它无法可靠捕获所有变化,且无法区分是否已翻译过。
- 封装一个
t('common_error')函数,供JS动态提示(如alert、Toast)调用 -
<select></select>的<option></option>需单独遍历,根据父级data-i18n查语言包中"xxx.options"数组逐个赋值 - SVG内
<text></text>需额外识别SVGTextElement类型做特殊处理
JSON语言包结构和加载必须防翻车
结构扁平、键名一致、路径固定,是避免加载失败和key错位的核心。别图省事塞进一个大对象里。每个语言一个文件:./locales/zh-Hans.json、./locales/en-US.json,内容全是顶层键值对,不嵌套。
所有文件键名必须严格一致;哪怕某语言暂时没翻译,也要留空字符串或占位符,否则JS查不到key就留白。加载失败时必须有fallback:
- 用
try/catch包住fetch(),捕获网络层错误 - 用
response.ok判断HTTP状态码是否为2xx - 降级顺序:先试完整码(如
zh-HK),再截主语言(zh),最后退到默认语言(如en) - 服务器返回JSON时,
Content-Type必须是application/json,否则fetch可能静默失败
真正容易被忽略的是:含HTML结构的文案(如“请阅读服务条款”)必须用innerHTML替换,但语言包里对应值要是可信纯HTML片段——不能带用户输入、不执行JS,否则有XSS风险。这比单纯替换textContent多一层校验成本,但绕不开。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











