一个简单的 JavaScript 的模板引擎

比较简单,直接贴代码吧:

(function (global) {

    var _version = '1.0.0',

        _setting = {

            openTag: '<#',          /*逻辑代码的开始标签*/

            closeTag: '#>',         /*逻辑代码的结束标签*/

            maskOpenTag: '<!-',     /*注释的开始标签*/

            maskCloseTag: '-!>'     /*注释的结束标签*/

        },

        _templateCache = {},

        _escapeHTML = function (str) {

            if (typeof str === 'string') {

                var reg = /&(?!#?\w+;)|<|>|"|'|\//g,

                    rules = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''', '/': '/' };

                return str.replace(reg, function (m) { return rules[m]; });

            }

            return str;

        },

        _compile = function (source, key) {

            if (typeof key != 'undefined' && typeof _templateCache[key] === 'function') {

                return _templateCache[key];

            }

            var code = (function () {/*剔除注释代码*/

                var arr = (source || '').split(_setting.maskOpenTag);

                arrayEach(arr, function (i, o) {

                    var _arr = o.split(_setting.maskCloseTag);

                    this[i] = _arr.length == 1 ?

                        (i == 0 ? _arr[0] : _setting.maskOpenTag + _arr[0]) : _arr[1];

                });

                return arr.join('');

            })();



            return _templateCache[key] = (function () {

                var codeArr = code.split(_setting.openTag),

                    funArr = [

                        'var $T = arguments[0];\n',

                        'var $data = this || { };\n',

                        'var $escapeHTML = $T.escapeHTML;\n',

                        'var $htmlArr = [];\n',

                        'var $write = function() { Array.prototype.push.apply($htmlArr, arguments); };\n'];



                arrayEach(codeArr, function (i, o) {

                    var arr = o.split(_setting.closeTag);

                    if (arr.length == 1) {

                        funArr.push(html(arr[0]));

                    } else {

                        funArr.push(logic(arr[0]), html(arr[1]));

                    }

                });



                funArr.push('return $htmlArr.join("");');



                try {

                    var fun = new Function(funArr.join(''));

                } catch (e) {

                    var fun = new Function('return "Template Error !"');

                }



                return function () {

                    try {

                        return Function.prototype.call.apply(fun, [arguments[0], _t]);

                    } catch (e) {

                        return e.name + ' : ' + e.message;

                    }

                };

            })();



            function arrayEach(arr, fun) {

                if (Object.prototype.toString.call(arr) === '[object Array]') {

                    if (typeof fun === 'function') {

                        for (var i = 0, len = arr.length; i < len; i++) {

                            Function.prototype.call.apply(fun, [arr, i, arr[i]]);

                        }

                    }

                }

            }



            function html(code) {

                code = code

                    .replace(/"/g, '\\"')

                    .replace(/\r/g, '\\r')

                    .replace(/\n/g, '\\n');

                return '$write("' + code + '");\n';

            }



            function logic(code) {

                code = code.replace(/^\s+/g, '');

                if (code.indexOf('==') === 0) {

                    return '$write(' + code.substring(2) + ');\n';

                } else if (code.indexOf('=') === 0) {

                    return '$write($escapeHTML(' + code.substring(1) + '));\n';

                } else {

                    return code + '\n';

                }

            }

        },

        _t = {

            version: _version,

            setting: _setting,

            templateCache: _templateCache,

            escapeHTML: _escapeHTML,

            compile: _compile

        };



    global.T = global.T || {};

    for (var it in _t) { global.T[it] = _t[it]; }

})(this);

     原理很简单,就是读取模版字符串,用字符串的 split 方法分解字符串然后解析处理,最终生成一个的javascript方法代码,再通过 new Function 创建一个 function

就算编译模版,编译后的模版其实就是一个 function ,这个 function 接收数据参数,下面是个示例:

<script id="t_tmp" type="text/template">

    <# if (Object.prototype.toString.call(this) === '[object Array]') { #>

        <table>

        <# for(var i = 0; i < this.length; i++) { #>

            <tr>

                <td><#= this[i]['name'] #></td>

                <td><#= this[i]['age'] #></td>

            </tr>

        <# } #>

        </table>

    <# } #>

</script>

 

var data = [

    { name: 'xiaoming', age: 23 },

    { name: 'xiaohong', age: 20 }

];

var html = T.compile($('#t_tmp').html(), 't_tmp')(data);

 用法也比较简单。

你可能感兴趣的:(JavaScript)