data-i18n仅作用于textcontent,必须为placeholder/title/alt等属性显式添加对应后缀(如data-i18n-placeholder),且需同步更新lang属性、滚动位置、表单状态及动态dom。

data-i18n 属性怎么标记才真正生效
只给 <h1 data-i18n="home.title"></h1> 加属性,但没处理 placeholder、title、alt 这些属性,切换语言后它们还是旧的。浏览器不会自动把 data-i18n 映射到所有文本相关属性上。
-
textContent类内容(<p></p>、<button></button>、<label></label>文字)靠data-i18n即可覆盖 -
placeholder必须用data-i18n-placeholder,title用data-i18n-title,alt用data-i18n-alt -
value一般不翻译(表单输入值属于用户数据),但<input type="submit">和<button></button>的显示文案建议统一走textContent更新 - 不要在
<script></script>、<style></style>、<pre class="brush:php;toolbar:false;"></pre>内部加data-i18n—— 这些节点不参与渲染,JS 替换无效
JSON 语言包加载失败时页面为啥空白
fetch 失败、响应不是 JSON、或 key 缺失时,JS 查不到值就留空,而用户看到的是一堆原始键名或空格 —— 这不是“没翻译”,是 fallback 没兜住。
- 路径必须动态拼接:
./locales/${lang}.json,别写死成./zh.json - 必须用
try/catch包裹fetch()和response.json(),捕获网络错误和解析异常 - fallback 顺序要严格:先试完整 BCP 47 码(如
zh-HK),再截主语言(zh),最后退到默认语言(如en) - 所有语言包结构必须扁平且键名完全一致;某语言暂未翻译也要保留键,设为空字符串:
"btn_submit": "" - 服务器返回 JSON 时,
Content-Type必须是application/json,否则fetch可能静默失败
为什么只改 document.documentElement.lang 屏幕阅读器仍读错
浏览器和屏幕阅读器按每个元素自身的 lang 属性决定语音、字体回退、标点间距 —— 不继承父级。根节点改了,已渲染的子元素完全不受影响。
- 切换语言后,必须遍历所有已有
lang属性的元素(如<p lang="en"></p>、<pre class="brush:php;toolbar:false;" lang="bash"></pre>),把它们的lang值也同步更新(除非明确要保留原语言) -
document.documentElement.lang必须设为标准 BCP 47 码(如zh-Hans、ja),不能填zh_CN或Chinese - 含 HTML 结构的文案(如 “请阅读服务条款”)要用
innerHTML替换,但语言包里对应值必须是可信纯 HTML 片段,不能带用户输入,否则有 XSS 风险 - 动态插入的 DOM(弹窗、AJAX 表格行、懒加载模块)插入后必须立即调用翻译函数,否则
data-i18n标记只是字符串,不会变成对应语言文本
切换语言时滚动位置和表单状态为何丢失
暴力替换文本或重载页面会清空输入框、丢掉焦点、跳回顶部 —— 用户体验直接断裂。
- 更新 DOM 前,用
getComputedStyle或window.scrollY记录当前滚动位置 - 批量更新完所有
data-i18n元素后,立刻执行window.scrollTo(0, y)恢复位置 - 表单输入值(
input.value、textarea.value、select.value)不要动,只更新 label、placeholder、title 等展示层 - 如果用了
Intl.DateTimeFormat或Intl.NumberFormat,切换后需重建实例,不能复用旧对象;moment.js 则需调用moment.locale('en') - 别用
window.location.reload()强刷 —— 破坏前进/后退栈,且无法保持路由参数和临时状态
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











