优先用textContent改纯文本,安全高效;插入HTML结构时用createElement+appendChild组合,避免innerHTML隐患;确保DOM加载完成后再操作,防止找不到元素或事件丢失。
直接用 JavaScript 做 DOM 文本层替换是最轻量、最可控的方式,但必须避开 innerHTML 全量重写和正则暴力匹配这两类典型翻车操作。
innerHTML?很多老教程教你在按钮点击时执行类似 document.body.innerHTML = zh_tran('t'),这会导致:
onclick、addEventListener 全失效)input、textarea 的 value 不在 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,别用 cookie:前者无网络开销、容量更大、API 更干净。关键点:
localStorage.getItem('zh_mode'),若为空再查 navigator.language
localStorage.setItem('zh_mode', 't'),然后立即执行 zh_tran('t')
storage 事件,在其他同源 tab 中同步更新(避免用户开两个页面,一个切繁体、一个还是简体)DOMContentLoaded 之前就执行转换,否则可能因 DOM 未就绪而漏节点JS 转换只管运行时 DOM,对以下三类无效:
<h1>欢迎</h1>)—— 必须靠 JS 转换::before { content: "登录"; })—— 浏览器不提供 API 修改伪元素文本,只能改 class 或用 JS 插入真实元素<text> 标签 —— JS 无法触达,得靠设计侧出双版本或用 WebFont + OpenType 特性(不推荐)最容易被忽略的是:接口返回的 JSON 文案(比如文章标题、评论内容)必须由后端按 Accept-Language 或客户端传参(如 ?lang=zh-TW)返回对应版本,前端 JS 转换只是兜底方案,不该承担主责。