必须为所有含文本的语义化标签显式设置 lang 属性,且与语言包一致;data-i18n 默认只替换 textContent,placeholder 等需加后缀;DOM 深度超 6 层会漏扫描;动态插入内容需立即翻译;微服务需用 closed Shadow DOM 隔离样式。

只改 document.documentElement.lang 是无效的
浏览器、屏幕阅读器、字体回退链、标点渲染规则,全部依赖每个元素自身的 你好lang 属性,而不是继承值。你执行 document.documentElement.lang = 'en' 后, 依然按中文规则渲染顿号宽度、语音朗读方式和字体 fallback,结果就是:文字没变、标点挤在一起、屏幕阅读器读错音、中文字体覆盖代码块。
必须显式同步所有含文本的语义化标签:
-
、、、等都得带lang,且值与当前语言包一致(如lang="zh-Hans") - 已有明确语义的
lang不可覆盖:、保留原值,这是合法混排 -
<script></script>和内部不参与文本渲染,加lang没用
data-i18n 只管 textContent,其他属性要显式声明
常见错误是只写 ,但切换语言后 placeholder 还是英文——因为 data-i18n 默认只替换元素文本内容,对 placeholder、alt、title、aria-label 完全无效。
必须加后缀显式绑定:
data-i18n-placeholder="search_hint"data-i18n-alt="avatar_desc"data-i18n-title="tooltip_info"data-i18n-aria-label="close_button"
value 属性一般跳过翻译(属于用户输入),但 和 的显示文案建议统一用 textContent 更新,避免提交时意外发出去
DOM 深度超 6 层会导致 data-i18n 节点漏扫描
当 实现 Markdown↔ HTML 互转,支持导出 PDF,用于用户请求的文档格式转换。data-i18n 出现在 这类纯 CSS 堆叠结构里,遍历逻辑常因性能阈值或截断跳过最内层节点——语言切换后文字不动,控制台也无报错。
验证方式:在 Elements 面板右键目标元素 → “Reveal in Elements panel”,手动数从 body 到该节点的层级,必须 ≤6。
修复手段:
- 把冗余 替换为语义标签:
、、,天然中断嵌套深度- 动态插入的 DOM(弹窗、表格行、懒加载模块)必须在
appendChild()后立即调用翻译函数,不能等全局扫描- SSR 首屏 HTML 中,若
data-i18n在第 7 层才出现,需调整服务端初始化脚本的遍历深度阈值微服务架构下
html和body样式必须隔离子应用一旦声明
body { font-size: 14px; },主应用的body { font-size: 16px; }就被覆盖;两个子应用都引入 normalize.css,html的scrollbar或font-smoothing设置会互相干扰。唯一可靠隔离手段是 Custom Elements +
attachShadow({ mode: 'closed' }):- 必须在
constructor()中调用,connectedCallback()已太晚 -
mode: 'open'等于放弃隔离,外部可通过el.shadowRoot直接注入恶意样式 - 子应用 HTML 片段不能直接
innerHTML = htmlString,否则内联和<script></script>逃逸至全局作用域
正确做法:用
DOMParser解析字符串,提取内容转为CSSStyleSheet实例,再通过shadowRoot.adoptedStyleSheets = [sheet]注入 - 动态插入的 DOM(弹窗、表格行、懒加载模块)必须在
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










