data-i18n标记必须覆盖所有可翻译节点,包括placeholder、title、alt、aria-label等属性,需显式使用data-i18n-placeholder等后缀;lang属性须逐层设置,动态节点插入后立即补lang;语言包加载需fetch校验mime类型并fallback;broadcastchannel需搭配localstorage初始化。

data-i18n 标记必须覆盖所有可翻译节点,包括属性和内联元素
只给 <h1></h1> 或 <p></p> 加 data-i18n 是不够的。placeholder、title、alt、aria-label 这些属性不会自动同步,必须显式标注。
常见错误是表单输入框切换语言后提示文字还是英文——因为漏了 data-i18n-placeholder;或者图片 alt 读错语音,因为没加 data-i18n-alt。
<input data-i18n="form.email" data-i18n-placeholder="form.email_placeholder"><img data-i18n-alt="logo.desc" src="logo.png">-
<button data-i18n="btn.submit" aria-label="btn.submit_aria"></button>需额外加data-i18n-aria-label - SVG 内的
<text></text>也要单独标,不能靠父容器继承
lang 属性必须逐层显式设置,不能只改 document.documentElement.lang
浏览器和屏幕阅读器按每个元素自身的 lang 属性决定语音引擎、字体 fallback、标点间距(如中文顿号 vs 英文 comma),不是继承来的。只设根节点 document.documentElement.lang = 'zh-CN',<img alt> 和 <title></title> 仍会用旧语言播报。
动态插入的节点(弹窗、AJAX 表格行)插入后必须立即补上 lang,否则辅助技术无法识别。
- 所有语义化容器(
<h1></h1>、<p></p>、<section></section>)都应带lang属性,值与当前语言包一致 - 已有明确多语言意图的节点(如
<pre class="brush:php;toolbar:false;" lang="bash"></pre>、<blockquote lang="ja"></blockquote>)切换主语言时需保留原lang,不覆盖 -
<script></script>和<style></style>里设lang无效,别浪费字符
语言包加载必须用 fetch + MIME 类型校验,不能硬编码或忽略 404
把 JSON 直接写进 JS 会导致构建体积膨胀、热更新困难;用 XMLHttpRequest 容易静默失败——比如服务器返回 text/plain MIME 或 404,但脚本照常执行,文案留空。
正确做法是路径统一为 ./locales/${lang}.json(如 ./locales/zh-HK.json),并做三层防护:
- 外层
try/catch捕获网络异常 - 检查
response.ok === true - 校验
response.headers.get('content-type')?.includes('application/json') - fallback 顺序:先试完整 BCP 47 码(
zh-HK),再截主语言(zh)
BroadcastChannel 必须搭配 localStorage 初始化,否则新标签页失联
BroadcastChannel 只发消息,不存状态。新打开的标签页默认收不到历史语言选择,也不会自动拉取当前语言——它是个空频道。
典型错误是只监听 bc.onmessage,却没在页面加载时主动从 localStorage 读取初始语言并设置 document.documentElement.lang,导致新标签页显示空白或旧语言。
- 用户切换语言时:先
localStorage.setItem('i18n-lang', 'en-US'),再bc.postMessage({ type: 'lang-change', lang: 'en-US' }) - 所有标签页监听到消息后,检查
event.data.sender !== ownId再执行更新,避免自扰 - 页面加载完成时,立即读取
localStorage.getItem('i18n-lang')并初始化语言包、lang属性、Intl 实例 - Safari 无痕模式下
localStorage可能抛QuotaExceededError,所有写操作必须包try/catch
<abbr></abbr>。它们不是“待翻译内容”,而是明确的多语言共存结构,必须显式声明 lang,且不能随主语言切换而改变。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











