直接用 JavaScript 操作 DOM 文本层进行简繁转换,是目前最轻量、最可控的方案。但核心在于,必须绕过两个典型的“翻车现场”:一是直接用 innerHTML 全量重写,二是用正则暴力匹配。这两招一旦使用,基本就告别可控性了。 为什么不能图省事,直接改 innerHTML? 很多老教程会教你
直接用 JavaScript 操作 DOM 文本层进行简繁转换,是目前最轻量、最可控的方案。但核心在于,必须绕过两个典型的“翻车现场”:一是直接用 innerHTML 全量重写,二是用正则暴力匹配。这两招一旦使用,基本就告别可控性了。
innerHTML?很多老教程会教你,在按钮点击时执行类似 document.body.innerHTML = zh_tran('t') 这种操作。表面上看一行代码搞定,但代价极其惨重:
长期稳定更新的攒劲资源: >>>点此立即查看<<<
onclick、addEventListener,在 DOM 被整体替换的瞬间,全部消失。input、textarea 里用户输入的内容,存储在 value 属性中,不在 innerHTML 里。直接替换会导致用户信息丢失。innerHTML 等于破坏了框架的基础,轻则报错,重则导致页面白屏。因此,这条路绝不能走。
zh_tran 函数,到底该怎么写才安全?一个合格的 zh_tran 函数,核心思想是“精准打击,绝不误伤”。它应该只遍历真正的文本节点(Node.TEXT_NODE),跳过元素节点和注释,同时保护好用户输入的内容。一个可行的实现逻辑如下:
function zh_tran(mode) {
const map = mode === 't' ? traditionalMap : simplifiedMap;
const walk = (node) => {
if (node.nodeType === Node.TEXT_NODE) {
const text = node.textContent;
// 过滤掉空格、换行、纯数字、英文等非中文段落,避免无效操作
if (/[\u4e00-\u9fa5]/.test(text)) {
node.textContent = text.replace(/[\u4e00-\u9fa5]/g, c => map[c] || c);
}
} else if (node.nodeType === Node.ELEMENT_NODE) {
// 跳过 input/textarea 的 value,但处理其 placeholder 属性
if (node.tagName !== 'INPUT' && node.tagName !== 'TEXTAREA') {
node.childNodes.forEach(walk);
} else if (node.hasAttribute('placeholder')) {
node.setAttribute('placeholder', node.getAttribute('placeholder').replace(/[\u4e00-\u9fa5]/g, c => map[c] || c));
}
}
};
walk(document.body);
}
这里尤其需要注意,traditionalMap 和 simplifiedMap 必须是预先加载好的、完整的双向映射对象,而不是简单的字符串 replace。因为中文字符存在许多“多对一”或“一对多”的情况,例如“裏”和“裡”、“着”和“著”。使用对象映射才能保证转换的准确性,否则漏转、错转是常见问题。
这个需求,使用 localStorage 是最合适的方案。它没有网络开销,容量大,API 干净,远优于 cookie。实现时需要注意几个关键点:
localStorage.getItem('zh_mode'),如果为空,可以再根据 navigator.language 判断用户的语言偏好,作为默认值。localStorage.setItem('zh_mode', 't') 保存状态,然后立即执行 zh_tran('t') 更新当前页面。storage 事件。当用户在一个标签页切换语言后,其他同源的标签页也能收到通知并自动更新。DOMContentLoaded 事件触发之前就执行转换。否则 DOM 可能尚未解析完成,导致遗漏许多节点,转换不彻底。最后需要指出,JS 的运行时转换作用范围有限,它对以下三类“硬骨头”基本无效:
欢迎
,只能依靠 JS 在运行时转换。content 属性生成的“登录”字样。浏览器不提供 API 修改伪元素的文本。唯一的办法是修改 CSS class,或用 JS 插入真实元素来替代。 标签里的内容,JS 基本无法触及。图片需要设计团队提供双版本,SVG 则可以考虑使用 WebFont 加 OpenType 特性(但非常复杂,不推荐)。这里有一个最容易被忽略的点:**接口返回的 JSON 文案,比如文章标题、用户评论,这些是 JS 转换的“盲区”**。正确的做法是,后端根据 Accept-Language 请求头,或客户端传参(例如 lang=zh-TW),直接返回对应语言的版本。前端 JS 转换,本质上只是一个“兜底”的补充方案,它不应该、也承担不了主要责任。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述