HTML国际化采用扁平化JSON语言包(路径locales/zh.json),键名一致无嵌套。data-i18n属性区分文本与placeholder/title/alt后缀,切换语言时同步更新元素lang属性(符合BCP47),并用try/catch加载语言包,提供fallback。
语言包的结构其实有硬性要求:必须扁平化,键名严格对齐,路径统一为locales/zh.json这种写法,HTTP 头要设成application/json,data-i18n属性还得区分后缀(placeholder/title/alt),lang属性按 BCP 47 标准同步更新并遍历子元素。少一个下划线,整页文案就可能消失。

键名对不上、某个语言文案全白、加载后部分文字未变化——这些问题通常源于 JSON 结构或路径设置不当。并非 JS 代码错误,而是语言包本身未对齐。
长期稳定更新的攒劲资源: >>>点此立即查看<<<
首先,每个语言使用独立文件,路径固定为 locales/zh.json、locales/en.json,避免随意改为 i18n/zh-CN.json 等不一致路径。其次,所有 JSON 必须采用扁平结构:禁止嵌套对象,{"home": {"title": "首页"}} 这种写法错误,应改为 {"home.title": "首页"}。此外,所有文件中的字段名(key)必须完全一致——即使 ja.json 中某句尚未翻译,也需保留 "home.title": "",否则 JS 无法查到 key 会直接留空。最后,HTTP 响应头必须包含 Content-Type: application/json,Nginx 或 Vercel 静态托管默认支持,但某些老旧内网服务器可能返回 text/plain,导致 response.json() 静默失败,此问题较常见。
仅给 添加属性,结果 placeholder、title、alt 全未生效——这不是 JS 漏处理,而是 HTML 标记不完整。
需要区分两种情况:textContent 类内容(如 、、)直接使用 data-i18n;属性类内容必须带后缀,例如 data-i18n-placeholder、data-i18n-title、data-i18n-alt,不能依赖 data-i18n 自动判断。另外,value 属性无需处理(表单输入值属于用户数据,非界面文案),但 label 文字需标记 data-i18n。对于包含 HTML 结构的文案(如“请阅读服务条款”),需使用 innerHTML 替换,对应语言包中的值必须是可信 HTML 片段,不可包含用户输入内容,否则存在 XSS 风险。
文字已替换,但屏幕阅读器仍用中文读英文页面,字体渲染异常,标点间距不对——问题不在翻译逻辑,而在于 lang 属性未及时更新。
首先需要明确,document.documentElement.lang 仅影响根节点,子元素的 lang 属性不会自动继承。浏览器和辅助技术根据每个元素自身的 lang 决定行为,因此切换时必须遍历所有已设置 lang 的元素(如 、),将其 lang 改为当前语言码,除非明确需要保留原语言。语言码必须符合 BCP 47 标准:zh-Hans 可用,zh_CN 或 chinese 会被忽略,导致 fallback 失败。此外,更新前使用 window.scrollY 记录位置,更新后立即 window.scrollTo(),否则 DOM 重排会跳回顶部,影响体验。
本地开发正常,上线后部分用户语言包加载失败、控制台无报错——很可能是 fetch 被拦截或 fallback 未兜底。
几个常见但易忽略的点:await fetch('./locales/' + lang + '.json') 不要裸写,必须包裹在 try/catch 中,且 catch 中需显式 console.error 并 fallback 到 en.json。IE11 不支持 dataset 驼峰访问,查 data-i18n 需使用 getAttribute('data-i18n') 兜底。URL 参数 lang=ja 优先级高于 localStorage,但 navigator.language 返回 zh-CN 时,应截取主语言码 zh 再查找 zh.json,避免因 zh-CN.json 不存在而 fallback 失败。此外,动态插入的 DOM(如弹窗、AJAX 表格行)插入后必须立即调用翻译函数,否则 data-i18n 节点不会被自动扫描。
真正难点不在于编写几行 JS 替换文字,而在于让每个 lang 属性、每个 data-i18n- 后缀、每个 JSON 键名都严丝合缝——差一个下划线,整页文案就可能消失。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述