zoukankan      html  css  js  c++  java
  • javascript 模板系统 ejs v7

    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 || {});
            }
          })();
    
    

    使用方法见如下例子:

    更新日志

    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
    更新默认界定符为<& &>,添加新的操作符<&~,对数据源的第一层属性名添加@前缀
    v7
    对参数进行多态化,因ejs天生支持模板的相互调用便去除<&:与<&~操作符
    

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

    //方式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"}
     })
    
    
  • 相关阅读:
    进阶之路 | 奇妙的View之旅
    进阶之路 | 奇妙的Window之旅
    进阶之路 | 奇妙的Activity之旅
    Laravel5.5 邮件发送报错:stream_socket_client()
    ThinkPHP中使用PHPMailer发送邮件
    php 实现密码错误三次锁定账号10分钟
    自定义函数实现字符串数组互转
    自定义函数实现判断一个字符串是否包含另外一个字符串
    PHP一个for循环输出9*9乘法表
    中国地区表SQL语句
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/1969718.html
Copyright © 2011-2022 走看看