data-i18n必须显式覆盖placeholder、title、alt、aria-label等所有可翻译属性,不能仅作用于textcontent;lang属性须逐元素设置而非依赖继承;动态dom需手动触发翻译;语言包加载须fetch+校验+降级。

data-i18n 标记必须覆盖所有可翻译属性,不能只扫 textContent
只给 <button>提交</button> 加 data-i18n="btn_submit",但漏掉 placeholder、title、aria-label 或 alt,切换语言后这些字段依然显示英文——这是最常被忽略的“半国际化”陷阱。
浏览器不会自动把 data-i18n 映射到所有属性;你得显式声明:
-
data-i18n→ 控制textContent(默认行为) -
data-i18n-placeholder→ 更新input的placeholder -
data-i18n-title→ 更新title属性(如 tooltip) -
data-i18n-alt→ 更新img的alt文本 -
data-i18n-aria-label→ 更新无障碍标签(必须!)
特别注意:value 属性通常不翻译(属用户输入数据),但 label 里的文本必须标记,且其 for 属性要与对应 input 的 id 严格一致,否则点击 label 失效。
lang 属性必须逐元素设置,不能靠继承
只改 document.documentElement.lang = 'zh-HK' 是无效的。浏览器和屏幕阅读器按每个元素自身的 lang 决定标点宽度、字体回退链、连字规则和语音播报——<title></title>、<meta name="description">、<img alt> 全都不继承父级 lang。
实操时必须手动或通过工具为每个含文本的语义化标签设 lang:
- 所有
<h1></h1>、<p></p>、<section></section>、<footer></footer>等容器加lang="zh-HK"(值与当前语言包一致) - 已有明确语种的代码块(如
<pre class="brush:php;toolbar:false;" lang="bash"></pre>)保留原lang,不覆盖——这是合法混排,不是 bug -
<script></script>和<style></style>内部不设lang,它们不参与文本渲染
否则你会遇到:中文顿号被当英文逗号渲染、<pre class="brush:php;toolbar:false;"></pre> 里代码字体被中文字体覆盖、SEO 元信息仍以英文索引。
动态插入的 DOM 必须手动触发翻译,不会自动监听
AJAX 加载弹窗、分页表格行、懒加载模块插入后,里面带 data-i18n 的节点只是静态字符串——i18n 函数不会自动扫描新节点。
每次插入后必须显式调用翻译函数,例如:
fetch('/api/orders')
.then(r => r.json())
.then(data => {
const rows = data.map(renderOrderRow).join('');
document.getElementById('order-table').innerHTML = rows;
translateDOM(document.getElementById('order-table')); // 关键:手动触发
});
常见遗漏点:
- 第三方组件(如日期选择器)内部 DOM 不受控,需查其文档看是否提供
locale配置项,而非指望 i18n 工具自动处理 - 使用
innerHTML替换含 HTML 结构的文案(如“请阅读使用条款”)时,语言包对应值必须是可信纯 HTML 片段,否则有 XSS 风险 - 若用
textContent更新,会丢失内嵌标签;若用innerHTML,必须确保服务端/语言包已做转义或白名单过滤
语言包加载必须用 fetch + 校验,不能硬编码或内联 JSON
把语言包直接写进 JS 文件,会导致构建体积膨胀、无法按需加载、热更新困难;用老式 XMLHttpRequest 又容易忽略 HTTP 状态码和 MIME 类型校验,404 或返回 text/plain 时静默失败。
正确做法是:
- 路径统一为
./locales/${lang}.json,支持 BCP 47(如zh-HK、en-US) - 加载必须用
fetch(),外层try/catch,内部检查response.ok和response.headers.get('content-type')?.includes('application/json') - fallback 顺序:先试完整码(
zh-HK),再截主语言(zh),最后 fallback 到默认语言(en) - 避免在
<script></script>中内联大段 JSON,既不利于缓存,也增加首屏解析压力
真正难的不是切换语言,而是让 lang、data-i18n、动态 DOM、语言包加载这四层逻辑在任意插入时机下都保持同步——稍一松懈,就会出现部分文本翻了、部分没翻、标点错位、辅助技术读错的混合状态。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











