data-i18n标记需显式添加于所有需翻译的HTML元素,值为语言包键名;配套更新document.documentElement.lang、localStorage及动态节点,并确保JSON语言包结构扁平、键名一致、加载有fallback。

data-i18n 标记 + 独立 JSON 语言包 + localStorage 持久化,是当前最轻量、不依赖构建工具、且能绕过框架锁定的可行路径。硬编码文案、只改 document.documentElement.lang、或靠 class/id 推断翻译键,都会在后续维护中出问题。
怎么给 HTML 元素打 data-i18n 标记才不漏不乱
所有要换语言的文本内容,必须显式加 data-i18n 属性,值为语言包里的键名,比如 "header_title" 或 "form_email_required"。
-
data-i18n只影响元素自身的textContent,不会动placeholder、title、alt这类属性——得用data-i18n-placeholder、data-i18n-title等带后缀的写法 - 表单控件、SVG 文本、按钮文字都要单独加,不能指望父容器一统到底
- 别在
<script></script>、<pre class="brush:php;toolbar:false;"></pre>、<style></style>里加——这些节点不渲染为用户可见文本,加了没效果 - 如果某段文案含 HTML(比如“请阅读服务条款”),就得用
innerHTML替换,但语言包里对应值必须是可信的纯 HTML 片段,否则有 XSS 风险
为什么必须同步更新 document.documentElement.lang 和子元素 lang
只改根节点的 lang,对已渲染的子元素完全无效。浏览器和屏幕阅读器按每个节点自己的 lang 属性决定语音、字体回退、标点间距——不是继承来的。
- 页面加载时,应设
document.documentElement.lang = 'zh-Hans'(注意:必须符合 BCP 47,zh_CN或chinese会被忽略) - 切换语言后,要遍历所有带
lang的元素,把非根节点的lang值也同步更新,比如一段日文引用<p lang="ja">https://www.php.cn/link/263b1243ca2dbeb358777ceabc4a2e4c</p>,不能跟着主语言切成lang="en" - 局部多语言内容(如代码块、英文术语、引文)必须显式写
lang="bash"或lang="en",不能指望全局覆盖
JSON 语言包怎么组织才能避免加载失败和 key 错位
结构扁平、键名一致、路径可预测,是稳定运行的前提。别把所有语言塞进一个大对象里,也不要把键名嵌套成 {"ui": {"header": {"title": "https://www.php.cn/link/263b1243ca2dbeb358777ceabc4a2e4c"}}}。
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
- 每种语言一个文件:
locales/zh.json、locales/en.json、locales/ja.json,内容全是顶层键值对 - 所有文件键名必须严格一致;某语言暂未翻译,也要留空字符串或占位符,否则 JS 查不到 key 就留白
- 加载用
fetch('./locales/${lang}.json'),别硬编码路径;拼接错误或网络失败时,必须try/catch包裹,并 fallback 到en.json或你设定的主语言包 - 如果用户选了
zh-HK但只有zh.json,需手动降级匹配(比如截取zh前缀),否则整页文案可能消失
切换语言时最容易被忽略的三个动作
只调用一次 replaceText() 函数替换文本,远远不够。以下三件事不做,用户刷新后就会回到旧语言,或屏幕阅读器卡住不动。
立即学习“前端免费学习笔记(深入)”;
- 更新
document.documentElement.lang后,必须立即执行localStorage.setItem('lang', 'ja')——要在语言包加载成功、文本更新完成之后,否则用户刷新页面会拿到未就绪的状态 - 不要用
window.location.reload()强刷页面;它破坏前进/后退栈,且无法保留当前滚动位置和表单输入状态 - 动态生成的内容(如通过 JS 插入的提示框、模态窗、下拉选项)也要走同一套翻译逻辑;否则新节点没
data-i18n,也不会被扫描到
lang 属性和 data-i18n 的更新时机稍有错位,就会导致语音朗读混乱或字体渲染异常。


















