必须为所有可见文本节点(如、、、)显式添加data-i18n属性,值为语言包中对应键名;placeholder、title、alt等属性须用data-i18n-placeholder等带后缀形式单独标注;含html结构的文案需用innerhtml替换且确保可信;、、等非渲染节点禁用data-i18n。

怎么用 data-i18n 标记才不漏关键文本和属性
所有要翻译的可见文本节点(<h1></h1>、<p></p>、<button></button>、<label></label>)必须显式加 data-i18n,值为语言包里的键名,比如 "nav_home"。但仅这样远远不够:
-
data-i18n只更新textContent,对placeholder、title、alt、aria-label完全无效 —— 必须额外写data-i18n-placeholder、data-i18n-title等带后缀的属性 -
<input type="submit">和<button></button>的文案建议统一走textContent更新,别依赖value(表单提交时可能误传) -
<select></select>的<option></option>需单独遍历处理,不能只标记<select></select>本身 - 含 HTML 结构的文案(如“请阅读服务条款”)必须用
innerHTML替换,且语言包里对应值要是可信纯 HTML 片段 —— 否则有 XSS 风险 - 别在
<script></script>、<style></style>、<pre class="brush:php;toolbar:false;"></pre>里加data-i18n—— 这些节点不渲染为用户可见文本,加了没效果
JSON 语言包结构和加载怎么避免翻车
语言包不是随便扔几个键值对就行,结构松散或路径错位会导致整页留白。关键约束很硬:
- 每个语言一个文件,路径固定为
./locales/zh.json、./locales/en.json、./locales/ja.json - 结构必须扁平:所有键都在顶层,禁止嵌套(如
{"ui": {"header": {"title": "..."}}}是灾难性设计) - 所有语言文件键名严格一致:某语言暂未翻译,也要保留键并设为空字符串
"btn_submit": "",否则 JS 查不到 key 就留白 -
fetch('./locales/en.json')必须用try/catch包裹,捕获TypeError: Failed to fetch或 404;再用response.ok判断 HTTP 状态码 - fallback 顺序必须是:先试完整 BCP 47 码(如
zh-HK),再截主语言(zh),最后退到默认语言(如en)
切换语言时为什么文字变了但屏幕阅读器还在读英文
只改 document.documentElement.lang 是典型误区。浏览器和屏幕阅读器按**每个元素自身的 lang 属性**决定语音、字体回退、标点间距 —— 不继承父级。
- 页面初始化时就要设
document.documentElement.lang = 'zh-Hans'(注意:必须符合 BCP 47,zh_CN或chinese会被忽略) - 切换语言后,必须遍历所有已带
lang属性的元素(如<p lang="en"></p>、<pre class="brush:php;toolbar:false;" lang="bash"></pre>),把它们的lang值也同步更新 —— 除非明确要保留原语言(如代码块、引文) - 局部多语言内容(如日文引用、英文术语)必须显式写
lang="ja"或lang="en",不能指望全局覆盖 - 别给
<script></script>或<style></style>加lang—— 它们不参与文本渲染,设了也白设
动态插入内容和第三方组件怎么同步语言
静态 DOM 能靠一次遍历搞定,但 AJAX 弹窗、分页表格、懒加载模块插入后,里面的 data-i18n 不会自动生效。
- AJAX 加载的弹窗(
<modal></modal>)插入 DOM 后,必须立即调用翻译函数遍历其内部所有[data-i18n]元素 - 分页表格每页通过
fetch获取新<tr> 行,新行插入后需手动触发翻译,否则 <code>data-i18n保持原始键名 - 用了
Intl.DateTimeFormat或Intl.NumberFormat的地方,切换语言后必须重建实例 —— 旧对象不会自动更新格式 - 如果用了
moment.js,记得调用moment.locale('en');若用原生Intl,需同步更新所有日期/数字格式化器 - 滚动位置、表单输入值、第三方组件(如日期选择器)状态必须保留 —— 切换前用
getComputedStyle记录位置,更新完再window.scrollTo()恢复,否则页面跳回顶部
真正麻烦的从来不是替换文字,而是让每一个
lang 属性、每一段动态插入的 DOM、每一个 Intl 实例都跟上语言变更节奏 —— 漏掉任意一环,用户看到的就只是“文字变了”,而辅助技术、字体渲染、交互反馈全都不对。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











