基于前端js模板替换的多语言方案思考
最近在做将一个系统多语言化的项目,系统使用的是ASP.NET,直接使用了一种已有的方案:在页面渲染时采用正则表达式替换{XXX:001 确定}格式的标记。但是这个方式增加了服务端的字符串处理,对页面性能有影响。
protected override void Render(HtmlTextWriter writer) { System.IO.StringWriter sw = new System.IO.StringWriter(); HtmlTextWriter htmltw = new HtmlTextWriter(sw); base.Render(htmltw); htmltw.Close(); sw.Close(); writer.Write(MultiLanguageUtil.Translate(sw.ToString())); }
所以在考虑是否可以将多语言的处理转移到前端,首先想到了一种简单暴力的js正则替换方式,先写个demo:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> </head> <body> <div id="container"> <div>{TMP:001 苹果}</div> <div>{TMP:002 梨子}</div> <div>{TMP:003 橙子}</div> <div>{TMP:004 葡萄}</div> <div>{TMP:005 全部}</div> <div>{TMPPPPP:005 全部}</div> <div>{TMP:105 张三</div> <div>TMP:106 李四}</div> </div> <script type="text/javascript"> var allResources = { 'TMP:001': { cn: '苹果', en: 'Apple' }, 'TMP:002': { cn: '梨子', en: 'Pear' }, 'TMP:003': { cn: '橙子', en: 'Orange' }, 'TMP:004': { cn: '葡萄', en: 'Grape' }, 'TMP:005': { cn: '全部', en: 'All' } }; var env = 'en'; //var env = 'cn'; var container = document.getElementById('container'); var docHtml = container.innerHTML; var docNew = []; var reg = /\{([A-Z][^\ }]+?) ([^\} ]+?)\}/g; var result; var lastIdx = 0; while ((result = reg.exec(docHtml)) != null) { var key = result[1]; var val = result[2]; cw(result[0], key, val); var resource = allResources[key]; if (resource) { var replacer = resource[env]; if (!replacer) { replacer = val; } docNew.push(docHtml.substring(lastIdx, result.index)); docNew.push(replacer); } else { docNew.push(docHtml.substring(lastIdx, result.index)); docNew.push(val); } lastIdx = result.index + result[0].length; } if (lastIdx < docHtml.length - 1) { docNew.push(docHtml.substring(lastIdx, docHtml.length)); } cw(docNew.join('').length); cw(docHtml.length); container.innerHTML = docNew.join(''); function cw(args) { console && console.log && console.log.apply(console, arguments); } </script> </body> </html>
这个很明显的一个缺陷是会使页面上的事件等丢失,这个可以通过调整事件绑定的顺序到替换模板之后来解决。
所以正在考虑另一种方式,也是正则替换:通过遍历dom的各个节点,替换innerText和attribute。(Todo)
2017-08-20 00:38:20更新:已经过去一年了,已经忘记这个todo了,哈哈哈,估计是没下文了的,:)
如果你觉得这篇文章对你有帮助或者使你有所启发,请点击右下角的推荐按钮,谢谢,:)