html国际化需分离键值、运行时加载、属性级替换;data-i18n标记文本节点,专用后缀处理placeholder等;语言包扁平统一、动态加载、带fallback;lang属性须精确设置并同步更新,动态节点需手动翻译,插值逻辑不可放入json。

HTML模板里的国际化变量注入,不是把翻译文本塞进 HTML 字符串里完事——关键在于「分离键名与值」+「运行时按需加载」+「属性级精准替换」。硬编码、innerHTML暴力替换、只改document.documentElement.lang,都会导致文案漏翻、XSS风险、屏幕阅读器失语或 fallback 失效。
data-i18n 属性怎么打才不漏不乱
所有要换语言的文本节点(<h1></h1>、<p></p>、<button></button>、<label></label>)必须显式加 data-i18n,值为纯英文键名,比如 "header_title" 或 "form_email_required"。
-
placeholder、title、alt不受data-i18n影响,得用对应后缀:data-i18n-placeholder、data-i18n-title、data-i18n-alt - 表单控件的
value一般不翻译(那是用户输入),但<button></button>的文字要用data-i18n;<select></select>的每个<option></option>得单独标记或走"xxx.options"数组约定 -
<script></script>、<style></style>、<pre class="brush:php;toolbar:false;"></pre>里加data-i18n没用——它们不渲染为可见文本 - 含 HTML 的文案(如“请阅读服务条款”)必须用
innerHTML替换,且语言包里该值要是可信的纯 HTML 片段,否则有 XSS 风险
JSON 语言包结构和加载逻辑怎么防翻车
语言包必须扁平、键对齐、路径可预测。别嵌套、别合并、别靠 JS 对象硬编码。
- 每个语言一个文件:
./locales/zh.json、./locales/en.json、./locales/ja.json,内容全是顶层键值对:{"header_title": "欢迎", "login_btn": "登录"} - 所有文件键名严格一致;某语言暂未翻译,也要保留键并设为空字符串:
"login_btn": "",否则 JS 查不到就留白 - 加载路径用
./locales/${lang}.json动态拼接,别写死./zh.json;fallback 顺序:先试完整码(zh-HK),再截主语言(zh),最后退到默认(en) -
fetch()必须包try/catch,还要判response.ok;失败时降级到内置 fallback 对象,而不是留空
切换语言时哪些东西必须同步更新
只替换文本是最低限度。浏览器和辅助技术依赖每个元素自身的 lang 属性做字体回退、标点间距、语音合成——不是继承根节点的。
- 必须设
document.documentElement.lang = 'zh-Hans'(注意 BCP 47 格式,zh_CN或chinese会被忽略) - 遍历所有已带
lang属性的子元素(如<p lang="ja"></p>、<pre class="brush:php;toolbar:false;" lang="bash"></pre>),仅同步那些本应随主语言变化的,局部多语言内容(代码块、引文)要保留原lang -
localStorage.setItem('lang', 'zh')要在语言包加载成功、DOM 更新完毕后再执行,否则刷新可能拿到未就绪状态 - 动态插入的节点(弹窗、AJAX 行)插入后必须立即调用翻译函数,不会自动触发
最容易被忽略的是:语言包里混入运行时变量(如用户名、时间格式),或把插值逻辑("hello {name}")和静态文案耦合在一起。这类内容必须由 JS 运行时处理,不能塞进 JSON —— 否则无法 fallback,也无法做安全转义。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











