基于前端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了,哈哈哈,估计是没下文了的,:)

posted @ 2016-07-28 22:38  liqipeng  阅读(1138)  评论(0)    收藏  举报