lang属性必须显式写在每个语义化容器上,仅设document.documentElement.lang无效;动态DOM插入后须立即调用翻译函数,否则内容不译。

lang属性必须显式写在每个语义化容器上
只改 document.documentElement.lang 是无效的。浏览器和屏幕阅读器按元素自身的 lang 属性判断语言行为,不是继承父级。漏设会导致:title、alt、placeholder 仍读旧语言;中文顿号、英文逗号间距错乱;<pre lang="bash"> 这类已有 lang 的节点字体回退链失效。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 所有含文本的语义化标签(
<h1>、<p>、<section>、<article>)都加lang,值与当前语言包一致 - 已有
lang的元素(如<pre lang="bash">)不覆盖——这是多语言混排,不是 bug -
<script>和<style>里写lang没用,它们不参与渲染
data-i18n 标记必须覆盖所有可翻译属性
只给 <button>提交</button> 加 data-i18n="btn_submit",却漏掉 placeholder、title、aria-label,结果切换后输入框提示还是英文,辅助技术无法同步播报。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 每个要翻译的元素至少带一个
data-i18n基础键 - 若含
placeholder,额外加data-i18n-placeholder;同理data-i18n-title、data-i18n-alt -
value属性一般不翻译(属用户输入数据),但<label for="xxx">内文本必须标记,且for与对应id严格匹配 - 含 HTML 结构的文案(如“请阅读使用条款”)必须用
innerHTML替换,语言包中对应值要是可信纯 HTML 片段,否则有 XSS 风险
动态插入的 DOM 必须手动触发翻译
弹窗、AJAX 表格行、insertAdjacentHTML 插入的内容,不会自动监听或翻译。框架层不接管时,就靠你补这一句。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- DOM 插入完成后立即调用翻译函数,例如
i18n.translate(el)或自定义的applyI18n(el) - 避免在插入前就调用翻译——节点还没挂到文档树,部分 selector 可能查不到
- 对重复插入的模块(如分页表格每页重载),确保每次插入后都执行,不要依赖“只运行一次”的逻辑
语言包加载必须用 fetch + try/catch + MIME 校验
硬编码 JSON 到 JS 里,会让构建产物膨胀、无法热更新;用 XMLHttpRequest 容易忽略 HTTP 状态码和 Content-Type,遇到 404 或服务器返回 text/plain 时静默失败。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 路径统一为
./locales/${lang}.json,例如./locales/zh-HK.json、./locales/en-US.json - 必须用
fetch(),外层包try/catch,内部检查response.ok和response.headers.get('content-type')?.includes('application/json') - fallback 顺序:先试完整 BCP 47 码(如
zh-HK),再截主语言(zh),最后兜底到en
最常被忽略的是 lang 属性的粒度控制和动态 DOM 的翻译时机——前者影响可访问性与排版,后者直接决定用户看到的是中文还是乱码。工程维护成本,往往就卡在这两个点上。



















