最轻量可控方案是data-i18n标记+json语言包+localstorage持久化;需为文本节点设data-i18n键名,placeholder等属性用对应后缀(如data-i18n-placeholder),同步更新document.documentelement.lang及所有显式lang子元素,并确保语言包扁平、bcp 47命名、加载有fallback。

直接用 data-i18n 标记 + 独立 JSON 语言包 + localStorage 持久化,就能构建出轻量、可复用、不依赖框架的多语言切换组件。硬编码文案、只改 textContent 或仅设 lang 属性,都会导致部分文字/属性不更新、屏幕阅读器失效或 SEO 断裂。
怎么给 HTML 元素打翻译标记才真正生效
所有要动态换语言的文本节点(<h1></h1>、<p></p>、<button></button>、<input>)必须显式加 data-i18n 属性,值是语言包里的键名;不能靠 id 或 class 推断——JS 不会自动猜。
-
data-i18n只作用于元素自身的textContent,比如<h1 data-i18n="header_title"></h1> - placeholder、title、alt 这类属性需额外加带后缀的标记:
data-i18n-placeholder、data-i18n-title、data-i18n-alt - 表单控件的
value一般不替换(避免清空用户已填内容),但若确需翻译(如按钮value),得用data-i18n-value - 含 HTML 结构的文案(如“请注册并登录”)要用
innerHTML替换,但语言包里对应值必须是可信纯 HTML 片段,否则有 XSS 风险 -
<script></script>、<pre class="brush:php;toolbar:false;"></pre>、<style></style>内部不渲染为可见文本,加data-i18n白费
JSON 语言包怎么组织才能避免加载失败
每个语言一个文件,路径固定为 ./locales/{lang}.json(如 ./locales/en.json、./locales/zh-Hans.json),结构必须扁平、纯键值对,且所有文件键名严格一致。
- 键名用英文小写+下划线,如
btn_submit,禁用空格、中文、驼峰或点号(home.title会增加解析逻辑,易出错) - 文件名必须符合 BCP 47 规范:
zh-Hans✅,zh_CN❌,chinese❌ - fetch 加载时必须用
try/catch包裹,网络失败或 JSON 解析错误不能中断整个流程 - fallback 机制不可省:用户选了
zh-HK但只有zh-Hans.json,就降级加载zh-Hans.json;最终兜底到en.json - 服务器需返回正确 MIME 类型
application/json,否则 fetch 可能静默失败
切换语言时必须同步更新哪些 DOM 属性
只替换文本是假切换。浏览器、屏幕阅读器、字体回退链都依赖 lang 属性做判断,它不是继承来的,而是逐节点生效的。
- 必须执行
document.documentElement.lang = 'zh-Hans',影响全局语义和拼写检查 - 所有显式写了
lang的子元素(如<p lang="en">API</p>、<pre class="brush:php;toolbar:false;" lang="bash"></pre>)必须手动遍历更新,否则它们仍按旧语言渲染 -
localStorage.setItem('lang', 'zh-Hans')要在语言包成功加载、DOM 更新完毕后再执行,否则刷新可能拿到未就绪的语言状态 - 不要用
window.location.reload(),会导致闪屏和状态丢失;切换应为无刷新 DOM 批量更新 - 初始语言判定顺序应为:URL 参数
?lang=ja→localStorage.getItem('lang')→navigator.language→ 默认en
为什么语言切换器本身也得被翻译
切换器按钮(如“中文”“English”)也是页面文本的一部分,如果没加 data-i18n,切到英文后按钮还显示“中文”,用户就无法再切回去。
- 按钮文案必须进语言包:
{"lang_zh": "中文", "lang_en": "English", "lang_ja": "日本語"} - 切换器 DOM 需绑定对应键,例如:
<button data-i18n="lang_zh"></button> - 动态插入的切换器(如弹窗内语言选择)要在插入后立即调用翻译函数,否则不会生效
- 国旗图标类资源(如
<img data-i18n-src="flag-zh">)需额外支持data-i18n-src处理逻辑,不能只靠文本替换
最易被忽略的是:混排内容中显式写的 lang 属性(比如一段英文引用、代码块、术语缩写)不会被 data-i18n 自动覆盖,必须单独维护;否则切语言后,那些节点的语音、字体、标点间距全乱套。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











