data-i18n必须覆盖所有可翻译属性而不仅是textcontent,需显式使用data-i18n-placeholder、data-i18n-title等后缀属性;lang属性须逐层设置且不可继承;动态dom需手动触发翻译;语言包加载须fetch+try/catch并严格校验mime与路径。

data-i18n标记必须覆盖所有可翻译属性,不只是textContent
只给加data-i18n="btn_submit",但漏掉placeholder、title、aria-label,切换语言后输入框提示、工具提示、屏幕阅读器播报全都是旧语言——这不是漏翻,是根本没配。
-
data-i18n只作用于元素的textContent,对属性完全无效 - 要翻译
placeholder,必须显式写data-i18n-placeholder="search_hint" - 同理:
data-i18n-title、data-i18n-alt、data-i18n-aria-label都得单独声明 -
value属性一般不翻译(属于用户数据),但label文本必须标,且for属性要和id严格对应,否则点击失效
lang属性必须逐层显式设置,不能靠documentElement继承
只执行document.documentElement.lang = 'en',页面文字不会变、屏幕阅读器仍读中文、顿号按英文间距渲染、<pre class="brush:php;toolbar:false;" lang="bash"></pre>字体被中文字体覆盖——浏览器和辅助技术只看每个元素自身的lang,不查父级。
- 所有含文本的语义化容器(
<h1></h1>、<p></p>、<section></section>、<footer></footer>)都应显式带lang,值与当前语言包一致(如lang="zh-Hans") - 已有
lang的特殊元素(如<pre class="brush:php;toolbar:false;" lang="bash"></pre>、<code lang="sql">)切换语言时保留原值,这是合法混排场景,不是错误 -
<script></script>和<style></style>里写lang无效,它们不参与文本渲染 - 动态插入的DOM(弹窗、表格行)插入后,不仅要调翻译函数,还得遍历并更新其内部所有
lang属性
语言包加载必须用fetch+try/catch,路径和MIME校验缺一不可
硬编码JSON、用XMLHttpRequest老写法、或把语言包直接塞进JS里,会导致构建体积膨胀、热更新失败、404静默、甚至因text/plain MIME类型被fetch拒绝而白屏。
- 路径统一为
./locales/${lang}.json(如./locales/zh-HK.json) - 必须用
fetch()+try/catch包裹,内部检查response.ok和response.headers.get('content-type') - 服务器返回必须是
application/jsonMIME,否则fetch可能不报错但response.json()抛异常 - fallback优先级:先试完整码(
zh-HK),再截主语言(zh),最后退默认(en);某语言键缺失,也得留空字符串"btn_submit": "",避免查不到key就跳过
DOM深度超6层时data-i18n节点会被跳过,不是bug是设计阈值
当data-i18n出现在<div><div><div><div><div><p data-i18n="msg"></p></div></div></div></div></div>这种纯CSS堆叠结构里,JS遍历逻辑或SSR初始化脚本常因性能阈值主动截断,导致切换语言后那段文字始终不更新,且控制台无任何报错。
- 用浏览器Elements面板右键 → “Reveal in Elements panel”,手动数从
body到目标节点的层级,必须≤6 - 冗余
<div>优先替换为语义标签:<code><main></main>、<section></section>、<article></article>,天然中断嵌套深度,同时支持i18n工具识别作用域 - 动态插入内容(如弹窗、AJAX表格行)必须在
appendChild()后立即调用翻译函数,不能依赖全局扫描 - SSR首屏HTML中,若
data-i18n在body下第7层才出现,服务端i18n初始化脚本大概率已跳过——这是架构级隐患,不是前端补丁能解决的











