javascript 模板系统 ejs v7

ejs第七版模板系统改进了易用性,移除了冗余功能并增强了参数传递灵活性。支持多种方式指定模板来源及数据,适用于本地元素或远程文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

javascript模板系统 ejs 第七版!

本版本只要是对其易用性进一些修改,去掉两个冗余的功能。

我发现我的模块系统天生就能实现模块套嵌,因此有关子模板导入的两个操作符去掉。

对参数进行多态化,可简单地传入一个字符串来指定目标元素的选择器或目标文件的URL(通过url(http://)来区分)与一个参数对象,也可以像EXT那样传入一个哈希。



      //dom.ejs v7 by 司徒正美
      //http://www.cnblogs.com/rubylouvre/archive/2010/10/04/1841933.html
      ;
      (function(){
        this.dom = {
          quote : String.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, '\\"') + '"';
          },
          mix : function(target, source ,override) {
            var i, ride = (override === void 0) || override;
            for (i in source) {
              if (ride || !(i in target)) {
                target[i] = source[i];
              }
            }
            return target;
          }
        }

        if(!String.prototype.trim){
          String.prototype.trim = function(){
            return this.replace(/^[\s\xa0]+|[\s\xa0]+$/g, '');
          }
        }
        ;
        (function(w,s){
          //http://blogs.msdn.com/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx
          s = ["XMLHttpRequest",
            "ActiveXObject('Msxml2.XMLHTTP.6.0')",
            "ActiveXObject('Msxml2.XMLHTTP.3.0')",
            "ActiveXObject('Msxml2.XMLHTTP')",
            "ActiveXObject('Microsoft.XMLHTTP')"];
          //IE专有的JScript方法:ScriptEngine,ScriptEngineBuildVersion,ScriptEngineMajorVersion,ScriptEngineMinorVersion,CollectGarbage,RuntimeObject和GetObject。
          if( !-[1,] && w.ScriptEngineMinorVersion() === 7 && location.protocol === "file:"){
            s.shift();
          }
          for(var i = 0 ,el;el=s[i++];){
            try{
              if(eval("new "+el)){
                dom.xhr = new Function( "return new "+el);
                break;
              }
            }catch(e){}
          }
        })(window);

        var
        metaObject = {
          '\b': '\\b',
          '\t': '\\t',
          '\n': '\\n',
          '\f': '\\f',
          '\r': '\\r',
          '\\': '\\\\'
        },
        _startOfHTML = "\t__views.push(",
        _endOfHTML = ");\n",
        _rAt = /(^|[^\w\u00c0-\uFFFF_])(@)(?=\w)/g,
        _partial = function(url){
          var xhr = dom.xhr();
          xhr.open("GET",url,false);
          xhr.setRequestHeader("If-Modified-Since","0");
          xhr.send(null);
          return xhr.responseText|| ""
        },
        defaults = {
          left: "<&",
          right: "&>"
        }
        var ejs = dom.ejs = function(obj,data){
          if(typeof obj === "string"){
            if(obj.indexOf("url(") === 0){
              obj = {
                url : obj.slice(4,-1),
                data: data
              }
            }else{
              obj = {
                selector:obj,
                data :data
              }
            }
          }
          dom.mix(obj, defaults,false);
          if(!obj.rLeft){
            obj.rLeft = new RegExp("\\s*"+obj.left+"\\s*")
            obj.rRight = new RegExp("\\s*"+ obj.right+"\\s*");
          }
          var key = obj.selector || obj.url;
 
          if(!ejs[key]){
            var  rAt = _rAt, startOfHTML = _startOfHTML, endOfHTML = _endOfHTML,partial = _partial,
            buff = ["var __views = [];\n"],str , logic;
            if(obj.selector){
              var el = document.getElementById(key);
              if (!el) throw "can not find the target element";
              str = el.text;
            }else {
              str = partial(obj.url);
              if (!str) throw "the target file does not exist";
            }
            var arr = str.trim().split(obj.rLeft),temp = [],i = 0,n = arr.length,els,segment;
            while(i < n){
              segment = arr[i++];
              els = segment.split(obj.rRight);
              if(segment.indexOf(obj.right) !== -1){//这里不使用el.length === 2是为了避开IE的split bug
                switch (els[0].charAt(0)) {
                  case "="://处理后台返回的变量(输出到页面的);
                    logic = els[0].substring(1);
                    if(logic.indexOf("@")!==-1){
                      temp.push(startOfHTML, logic.replace(rAt,"$1data."), endOfHTML);
                    }else{
                      temp.push(startOfHTML, logic, endOfHTML);
                    }
                    break;
                  case "#"://处理注释
                    break;
                  default://处理逻辑
                    logic = els[0];
                    if(logic.indexOf("@")!==-1){
                      temp.push(logic.replace(rAt,"$1data."), "\n");
                    }else{
                      temp.push(logic, "\n");
                    }
                }
                //处理静态HTML片断
                els[1] &&  temp.push(startOfHTML, dom.quote.call(null,els[1]), endOfHTML)
              }else{
                //处理静态HTML片断
                temp.push(startOfHTML, dom.quote.call(null,els[0]), endOfHTML)
              }
            }
            ejs[key] = new Function("data",buff.concat(temp).join("")+';return __views.join("");');
          }
          return  ejs[key](obj.data || {});
        }
      })();

使用方法见如下例子:

<!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <meta content="IE=8" http-equiv="X-UA-Compatible"/> <title>javascript 模板系统 ejs v6 by 司徒正美</title> <style type="text/css"> table { border:1px solid #a9ea00; border-collapse:collapse; width:80%; } td{ border:1px solid #a9ea00; padding:0; text-align:center; } </style> <script> //dom.ejs v7 by 司徒正美 //http://www.cnblogs.com/rubylouvre/archive/2010/10/04/1841933.html ; (function(){ this.dom = { quote : String.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, '\\"') + '"'; }, mix : function(target, source ,override) { var i, ride = (override === void 0) || override; for (i in source) { if (ride || !(i in target)) { target[i] = source[i]; } } return target; } } if(!String.prototype.trim){ String.prototype.trim = function(){ return this.replace(/^[\s\xa0]+|[\s\xa0]+$/g, ''); } } ; (function(w,s){ //http://blogs.msdn.com/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx s = ["XMLHttpRequest", "ActiveXObject('Msxml2.XMLHTTP.6.0')", "ActiveXObject('Msxml2.XMLHTTP.3.0')", "ActiveXObject('Msxml2.XMLHTTP')", "ActiveXObject('Microsoft.XMLHTTP')"]; //IE专有的JScript方法:ScriptEngine,ScriptEngineBuildVersion,ScriptEngineMajorVersion,ScriptEngineMinorVersion,CollectGarbage,RuntimeObject和GetObject。 if( !-[1,] && w.ScriptEngineMinorVersion() === 7 && location.protocol === "file:"){ s.shift(); } for(var i = 0 ,el;el=s[i++];){ try{ if(eval("new "+el)){ dom.xhr = new Function( "return new "+el); break; } }catch(e){} } })(window); var metaObject = { '\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '\\': '\\\\' }, _startOfHTML = "\t__views.push(", _endOfHTML = ");\n", _rAt = /(^|[^\w\u00c0-\uFFFF_])(@)(?=\w)/g, _partial = function(url){ var xhr = dom.xhr(); xhr.open("GET",url,false); xhr.setRequestHeader("If-Modified-Since","0"); xhr.send(null); return xhr.responseText|| "" }, defaults = { left: "<&", right: "&>" } var ejs = dom.ejs = function(obj,data){ if(typeof obj === "string"){ if(obj.indexOf("url(") === 0){ obj = { url : obj.slice(4,-1), data: data } }else{ obj = { selector:obj, data :data } } } dom.mix(obj, defaults,false); if(!obj.rLeft){ obj.rLeft = new RegExp("\\s*"+obj.left+"\\s*") obj.rRight = new RegExp("\\s*"+ obj.right+"\\s*"); } var key = obj.selector || obj.url; if(!ejs[key]){ var rAt = _rAt, startOfHTML = _startOfHTML, endOfHTML = _endOfHTML,partial = _partial, buff = ["var __views = [];\n"],str , logic; if(obj.selector){ var el = document.getElementById(key); if (!el) throw "can not find the target element"; str = el.text; }else { str = partial(obj.url); if (!str) throw "the target file does not exist"; } var arr = str.trim().split(obj.rLeft),temp = [],i = 0,n = arr.length,els,segment; while(i < n){ segment = arr[i++]; els = segment.split(obj.rRight); if(segment.indexOf(obj.right) !== -1){//这里不使用el.length === 2是为了避开IE的split bug switch (els[0].charAt(0)) { case "="://处理后台返回的变量(输出到页面的); logic = els[0].substring(1); if(logic.indexOf("@")!==-1){ temp.push(startOfHTML, logic.replace(rAt,"$1data."), endOfHTML); }else{ temp.push(startOfHTML, logic, endOfHTML); } break; case "#"://处理注释 break; default://处理逻辑 logic = els[0]; if(logic.indexOf("@")!==-1){ temp.push(logic.replace(rAt,"$1data."), "\n"); }else{ temp.push(logic, "\n"); } } //处理静态HTML片断 els[1] && temp.push(startOfHTML, dom.quote.call(null,els[1]), endOfHTML) }else{ //处理静态HTML片断 temp.push(startOfHTML, dom.quote.call(null,els[0]), endOfHTML) } } ejs[key] = new Function("data",buff.concat(temp).join("")+';return __views.join("");'); } return ejs[key](obj.data || {}); } })(); </script> <script> window.onload = function(){ var trs = [ {name:"隐形杀手",age:29,sex:"男"}, {name:"索拉",age:22,sex:"男"}, {name:"fesyo",age:23,sex:"女"}, {name:"恋妖壶",age:18,sex:"男"}, {name:"竜崎",age:25,sex:"男"}, {name:"你不懂的",age:30,sex:"女"} ] var lis = { aaa:"AAA", bbb:"BBB", ccc:"CCC" } var tmpl = dom.ejs("js_table_tmpl",{ title:"dom.ejs v7 ", name:"司徒正美", trs:trs, lis:lis, href:"http://images.cnblogs.com/cnblogs_com/rubylouvre/202906/o_type4.jpg" }); document.getElementById("js_table_tc").innerHTML = tmpl; } </script> </head> <body> <script type="tmpl" id="js_table_tmpl"> <h2><&= @title &> by <&= @name &></h2> <table> <& for(var i=0,tl = @trs.length,tr;i < tl;i++){ &> <& tr = @trs[i]; &> <tr> <td><&= tr.name &></td> <td><&= tr.age &></td> <td><&= tr.sex || "男" &></td> <&= dom.ejs("js_tds_tmpl",{}) &> </tr> <& } &> </table> < 怎么可能不支持图片 &> <img src="<&= @href &>"> <ol><&= dom.ejs("js_lis_tmpl",@lis) &></ol> </script> <script type="tmpl" id="js_lis_tmpl"> <li><&= @aaa &></li> <li><&= @bbb &></li> <li><&= @ccc &></li> </script> <script type="tmpl" id="js_tds_tmpl"> <td>静态的表格</d> <td>静态的表格</d> <td>静态的表格</d> </script> <div id="js_table_tc"> </div> </body> </html>

运行代码

更新日志

v1
默认界定符为,当然也可以自定义界定符,只支持当前页面的script元素做模板
http://www.cnblogs.com/rubylouvre/archive/2010/08/10/1796383.html
v2
改进算法提速,比John Resig的 Micro-Templating模板更能应对复杂的模板
http://www.cnblogs.com/rubylouvre/archive/2010/08/22/1805914.html
v3
http://www.cnblogs.com/rubylouvre/archive/2010/08/25/1807789.html
增添了局部模板功能
v4
http://www.cnblogs.com/rubylouvre/archive/2010/08/31/1813122.html
对v3的结构进行优化,支持远程的独立文件做模板
v5
http://www.cnblogs.com/rubylouvre/archive/2010/08/31/1813122.html
尝试新的算法
v6
http://www.cnblogs.com/rubylouvre/archive/2010/10/05/1841933.html
更新默认界定符为,添加新的操作符

参数多态化,四种传参方式

//方式1
dom.ejs("id",{aa:"aaa",bb:"bbb"})
//方式2
dom.ejs("url(http://aaa/tmpl.html)",{aa:"aaa",bb:"bbb"})
//方式3
dom.ejs({
 selector:"id",
 data    : {aa:"aaa",bb:"bbb"}
 });
//方式4
dom.ejs({
 url:"http://aaa/tmpl.html",
 data    : {aa:"aaa",bb:"bbb"}
 })

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值