HTML多语言需分清charset与lang作用:charset仅解码字节,lang控制语言行为;meta charset必须置于head最前;lang属性须逐节点设置且符合BCP 47;data-i18n需覆盖所有可翻译属性;JSON语言包加载须防错降级并动态插入DOM后立即翻译。

HTML 本身不靠“编码设置”来处理多语言内容,charset 只管字节解码,不管语言切换。真正决定多语言行为的是 lang 属性、data-i18n 标记和语言包加载逻辑——搞混这两者,页面会显示乱码或翻译失效,但原因完全不同。
为什么 <meta charset="UTF-8"> 必须放在 <head> 最前面
浏览器解析 HTML 时,一旦遇到非 ASCII 字符(比如中文、日文、阿拉伯字母),会立刻用当前已知的编码去解码。如果 <meta charset> 写在 <script> 或 <style> 后面,前面那段脚本或样式里的字符串可能已被错误解码成乱码,再改 charset 也救不回来。
-
<head><meta charset="UTF-8"><title>你好</title></head>✅ 正确:标题文字能正常显示 -
<head><script>console.log("你好")</script><meta charset="UTF-8"></head>❌ 危险:JS 字符串可能已按 ISO-8859-1 解码,输出 -
<meta>绝不能写进<body>,浏览器直接忽略
lang 属性不是装饰,必须逐节点更新
只执行 document.documentElement.lang = "zh-Hans",页面视觉上像切了语言,但屏幕阅读器仍读英文、:lang(zh) CSS 不生效、拼写检查错位——因为浏览器在 DOM 初始解析阶段就锁定了每个节点的 lang 值,运行时改根节点不影响子节点。
- 所有显式带
lang的元素都得手动遍历更新:<p lang="en">API</p>→ 切换时需设为lang="zh-Hans" - 技术块如
<pre lang="bash">或引用内容<blockquote lang="ja">应加data-keep-lang显式跳过 -
lang值必须严格符合 BCP 47:用zh-CN,不用zh_CN或chinese,否则全链路失效
data-i18n 标记必须覆盖所有可翻译属性,不能只靠 textContent
给 <h1 data-i18n="header_title"> 加标记,只解决了文本内容;但 placeholder、title、alt、value 这些属性完全不受影响。用户切换语言后,搜索框占位符还是英文,图片 alt 还是旧值,按钮文字可能消失(某些浏览器优先取 value 而非 textContent)。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
立即学习“前端免费学习笔记(深入)”;
- 占位符必须写
data-i18n-placeholder="search_hint",不能指望通用逻辑自动识别 - 按钮文字若需翻译,得同时加
data-i18n="btn_submit" data-i18n-value="btn_submit" -
<label data-i18n="form_email"><input></label>:label 文字必须标记,否则屏幕阅读器读不到新文本 -
<select data-i18n="country_select"><option value="CN">中国</option></select>:option 内容需单独遍历替换,不能只靠父级键名
JSON 语言包加载失败会导致大片空白,必须防错降级
fetch 失败或 key 缺失时,langPack[key] 返回 undefined,赋给 textContent 就是空字符串——用户看到的不是“未翻译”,而是整段消失。
- 路径必须动态拼接:
./locales/${lang}.json,别硬编码./zh.json - fetch + json 解析必须包在
try/catch里,失败时 fallback 到默认语言(如en.json) - 所有语言文件结构必须扁平且键名对齐:
{"header_title": "首页"},缺字段也要留空字符串,不能漏键 - 服务器返回 JSON 时,HTTP
Content-Type必须是application/json,否则 fetch 可能静默失败
最易被忽略的点:动态插入的 DOM(弹窗、AJAX 表格行)插入后不会自动翻译,必须立即调用翻译函数;滚动位置不保存的话,更新完 DOM 页面会闪回顶部。


















