多语言实现必须绑定lang属性、用data-i18n标记文案、校验fetch响应、动态插入后手动翻译、持久化语言偏好。

多语言按钮必须绑定到 lang 属性而非 class 或自定义 data 属性
浏览器原生支持 lang 属性语义,屏幕阅读器、翻译插件、CSS 伪类(如 :lang(zh))都依赖它。用 data-lang 或 class="zh" 做切换,会导致无障碍失效、样式无法精准作用、后续扩展困难。
实操建议:
- 根元素
初始设lang="zh",按钮点击后只改这一个属性:document.documentElement.lang = 'en' - 所有语言相关文案必须包裹在带
data-i18n的标签里,例如 - 不要用 innerHTML 直接写死中文,哪怕只是“仪表盘”三个字——后续加日语或阿拉伯语时,全量替换成本极高
fetch() 加载语言包时必须校验 response.ok 和 Content-Type
线上最常见问题:按钮点了没反应,控制台无报错,但文案仍是英文。实际是 Nginx 返回了 404 HTML 页面,而 response.json() 报错被静默吞掉。
实操建议:
- 语言包路径固定为
./locales/,服务端确保该路径返回${lang}.jsonContent-Type: application/json - fetch 后立刻检查:
if (!res.ok || !res.headers.get('content-type')?.includes('application/json')) throw new Error('Invalid locale response') - 失败时 fallback 到
en.json,但要记录 console.warn,否则上线后词库缺失完全不可见
动态插入 DOM 后必须手动调用翻译函数
仪表盘常有 tab 切换、弹窗、懒加载表格等场景。这些区域的 HTML 是 JS 插入的,data-i18n 不会自动生效——DOM 就绪和翻译就绪是两件事。
实操建议:
- 封装
translateElement(el),遍历el.querySelectorAll('[data-i18n]'),查词库填textContent或placeholder - 每次
innerHTML = ...或appendChild()后,立刻执行translateElement(insertedNode) - 不要在
DOMContentLoaded里只扫一次document.body,那对后续插入的节点完全无效
按钮状态同步容易漏掉 URL hash 和 localStorage
用户刷新页面后语言重置,或从分享链接进来的用户看到错误语言,都是因为没把选择持久化。
实操建议:
- 点击按钮时,同时写入:
localStorage.setItem('preferred-lang', 'ja')和history.replaceState(null, '', `?lang=ja`) - 初始化时优先读 URL 参数
lang,其次 fallback 到localStorage,最后才用navigator.language - 别用
cookie存语言偏好——HTTP 请求会带上,无意义增加开销;也别用sessionStorage,关页即丢
真正难的不是切换动作本身,而是让所有动态内容、异步区块、第三方组件都响应这个 lang 变更——它们不会自动重 render,得靠你主动触发。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











