改document.documentElement.lang无效,因浏览器和屏幕阅读器按各元素自身lang属性判断语言行为,不继承父级;必须逐个更新语义化标签的lang属性并同步调用翻译函数。

为什么改了 document.documentElement.lang 文本还是不换
因为 document.documentElement.lang 只影响根节点的语言声明,浏览器和屏幕阅读器不会据此重绘或重读已有子元素。你看到的“没换”其实是 DOM 已渲染完毕、JS 仅改了 lang 属性但没动文本内容。
常见错误现象:<h1 data-i18n="home.title">首页</h1> 切换语言后仍显示“首页”,控制台也没报错——说明 data-i18n 没被扫描到,或语言包加载失败,或键名对不上。
- 先检查是否调用了翻译函数(如
translateAll()),不是设完lang就自动生效 - 用浏览器 Elements 面板搜索
data-i18n,确认目标元素确实带这个属性(别漏写、别拼错、别藏在<script></script>或<pre class="brush:php;toolbar:false;"></pre>里) - 打开 Network 面板,看
./locales/zh.json这类请求是否 200,响应体是不是合法 JSON(注意 BOM 和 UTF-8 编码问题) - 在控制台执行
console.log(i18nData?.['home.title']),确认语言包里真有这个 key,且值非空字符串
data-i18n 生效了但 placeholder/alt 还是英文
data-i18n 默认只更新元素的 textContent,对属性完全无效。这是最常被忽略的漏点,不是 bug,是设计如此。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 必须显式加带后缀的标记:
<input data-i18n-placeholder="search.hint" placeholder="Search"> - 同理处理:
data-i18n-alt、data-i18n-title、data-i18n-aria-label - 别碰
value属性——表单输入值属于用户数据,不应翻译;但<button></button>显示文案建议统一走textContent更新 - 含 HTML 的文案(如“请阅读服务条款”)要用
innerHTML替换,且语言包里对应值必须是可信纯 HTML 片段(不能拼接用户输入)
切换后屏幕阅读器仍读错、顿号间距乱、中文字体没生效
这些都不是文本没换,而是 lang 属性没同步更新到具体语义元素上。浏览器按每个元素自己的 lang 决定语音、标点、字体回退,不继承父级。
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
调试步骤:
- 用 Elements 面板选中一段中文文字,右键 → “Edit as HTML”,看它是否有
lang="zh-Hans";没有?就是漏设 - 执行
document.querySelectorAll('[lang]'),检查返回列表是否覆盖所有含文本的语义标签(<p></p>、<section></section>、<footer></footer>等) - 切换语言时,必须遍历这些元素并重设:
el.lang = 'zh-Hans';特别注意保留已有的多语言混排,比如<pre class="brush:php;toolbar:false;" lang="bash"></pre>不要被覆盖 - 验证 BCP 47 格式:用
zh-Hans,别用zh_CN、chinese——写错会导致 CSS:lang(zh-Hans)伪类不匹配、i18n 库 fallback 失败
动态插入的 DOM(弹窗、AJAX 表格行)怎么补翻译
全局扫描函数(如 translateAll())只在初始化或手动触发时运行,不会监听新节点。插入后不处理,就永远是默认语言。
正确做法:
- 在
appendChild()或insertAdjacentHTML()后立即调用翻译函数,例如:translateElement(newRow, 'table.row') - 避免深度嵌套:DOM 路径从
到data-i18n元素超过 6 层时,部分遍历逻辑可能跳过(尤其老浏览器或性能敏感场景) - 用语义化标签替代纯
<div> 堆叠:<code><main></main>、<article></article>天然中断嵌套层级,也便于工具识别作用域 - IE11 不支持
element.dataset.i18n,需兜底用element.getAttribute('data-i18n')
真正卡住人的往往不是“怎么切”,而是“切完谁来管状态”:表单输入值、滚动位置、第三方组件(如日期选择器)的语言实例、甚至 MutationObserver 是否监听到新节点——这些细节不串起来,调试就会陷入“文本换了但体验崩了”的怪圈。


















