Ruby's Louvre

每天学习一点点算法

导航

javascript 模板系统 ejs v2

本版本主要是对原模板系统进行提速,去掉消耗巨大的辅助函数。本来想用它与John Resig的 Micro-Templating比较一下速度,发现对方无法处理复杂的模板,残念。

 //司徒正美 javascript template - http://www.cnblogs.com/rubylouvre/ - MIT Licensed
      (function () {
                if(!String.prototype.trim){
                    String.prototype.trim = function(str) {
                        return this.replace(/^[\s\xa0]+|[\s\xa0]+$/g, '');
                    }
                }
                var dom = {
                    quote: function (str) {
                        str = str.replace(/[\x00-\x1f\\]/g, function (chr) {
                            var special = metaObject[chr];
                            return special ? special : '\\u' + ('0000' + chr.charCodeAt(0).toString(16)).slice(-4)
                        });
                        return '"' + str.replace(/"/g, '\\"') + '"';
                    }
                },
                metaObject = {
                    '\b': '\\b',
                    '\t': '\\t',
                    '\n': '\\n',
                    '\f': '\\f',
                    '\r': '\\r',
                    '\\': '\\\\'
                },
                parser = document.createElement("div"),
                startOfHTML = "\t__views.push(",
                endOfHTML = ");\n";
           
                //onsite,可选,Boolean,是否就地替换掉模板容器,默认true,如果为false,则返回一个文档碎片,交由用户自己插入到需要的地方
                dom.ejs = function (obj) {
                    var onsite = obj.onsite === void 0 ,
                    left = obj.left || "<%",
                    right =obj.right || "%>",
                    selector = obj.selector,
                    isLeft = true,
                    buff = ["var __views = [];\n"],
                    fragment = document.createDocumentFragment(),
                    el = document.getElementById(selector),
                    ejs = dom.ejs;
                    if (!el) throw "找不到目标元素";
                    var str = el.text.trim();
                    if(!ejs[selector]){
                        while(str.length){
                            var condition = isLeft ? left :right;
                            var index = str.indexOf(condition);
                            if(index !== -1){//取左边
                                var text = str.slice(0,index);
                                if(isLeft){
                                    buff.push(startOfHTML, dom.quote(text.trim()), endOfHTML);
                                }else{
                                    switch (text.charAt(0)) {
                                        case "#"://处理注释
                                            break;
                                        case "="://处理后台返回的变量(输出到页面的);
                                            buff.push(startOfHTML, text.slice(1), endOfHTML)
                                            break;
                                        default:
                                            buff.push(text, "\n")
                                    };
                                }
                            }else{
                                if(isLeft){
                                    buff.push(startOfHTML, dom.quote(str), endOfHTML);
                                    break;
                                }else{
                                    throw "在字符串{{ "+dom.quote(str)+" }}中找不到右界定符"+right
                                }
                            }
                            str = str.slice(index+2).trim();
                            isLeft = !isLeft;
                        }
                        ejs[selector] = new Function("json", "with(json){"+buff.join("") + '};return __views.join("");')
                    }
                    parser.innerHTML = ejs[selector](obj.json || {});
                    while (parser.firstChild) {
                        fragment.appendChild(parser.firstChild)
                    }
                    return onsite ? el.parentNode.replaceChild(fragment, el) : fragment;
                };
                window.dom = dom;

            })();

John Resig的 Micro-Templating(报错)

第一个版本:

第二个版本:

下一版本计划将加入局部模板与helper方法。

posted on 2010-08-22 21:06  司徒正美  阅读(3337)  评论(7编辑  收藏  举报