baiduTemplate

/**

  • baiduTemplate簡(jiǎn)單好用的Javascript模板引擎 1.0.6 版本

  • http://baidufe.github.com/BaiduTemplate

  • 開源協(xié)議:BSD License

  • 瀏覽器環(huán)境占用命名空間 baidu.template ,nodejs環(huán)境直接安裝 npm install baidutemplate

  • @param str{String} dom結(jié)點(diǎn)ID,或者模板string

  • @param data{Object} 需要渲染的json對(duì)象,可以為空。當(dāng)data為{}時(shí),仍然返回html。

  • @return 如果無data,直接返回編譯后的函數(shù);如果有data,返回html。

  • @author wangxiao

  • @email 1988wangxiao@gmail.com
    */
    ;(function(window){

    //取得瀏覽器環(huán)境的baidu命名空間,非瀏覽器環(huán)境符合commonjs規(guī)范exports出去
    //修正在nodejs環(huán)境下,采用baidu.template變量名
    var baidu = typeof module === 'undefined' ? (window.baidu = window.baidu || {}) : module.exports;

    //模板函數(shù)(放置于baidu.template命名空間下)
    baidu.template = function(str, data){

      //檢查是否有該id的元素存在,如果有元素則獲取元素的innerHTML/value,否則認(rèn)為字符串為模板
      var fn = (function(){
    
          //判斷如果沒有document,則為非瀏覽器環(huán)境
          if(!window.document){
              return bt._compile(str);
          };
    
          //HTML5規(guī)定ID可以由任何不包含空格字符的字符串組成
          var element = document.getElementById(str);
          if (element) {
          //取到對(duì)應(yīng)id的dom,緩存其編譯后的HTML模板函數(shù)
              if (bt.cache[str]) {
                  return bt.cache[str];
              };
    
              //textarea或input則取value,其它情況取innerHTML
              var html = /^(textarea|input)$/i.test(element.nodeName) ? element.value : element.innerHTML;
              return bt._compile(html);
    
          }else{
    
              //是模板字符串,則生成一個(gè)函數(shù)
              //如果直接傳入字符串作為模板,則可能變化過多,因此不考慮緩存
              return bt._compile(str);
          };
    
      })();
    
      //有數(shù)據(jù)則返回HTML字符串,沒有數(shù)據(jù)則返回函數(shù) 支持data={}的情況
      var result = bt._isObject(data) ? fn( data ) : fn;
      fn = null;
    
      return result;
    

    };
    //取得命名空間 baidu.template
    var bt = baidu.template;

    //標(biāo)記當(dāng)前版本
    bt.versions = bt.versions || [];
    bt.versions.push('1.0.6');

    //緩存 將對(duì)應(yīng)id模板生成的函數(shù)緩存下來。
    bt.cache = {};

    //自定義分隔符,可以含有正則中的字符,可以是HTML注釋開頭 <! !>
    bt.LEFT_DELIMITER = bt.LEFT_DELIMITER||'<%';
    bt.RIGHT_DELIMITER = bt.RIGHT_DELIMITER||'%>';

    //自定義默認(rèn)是否轉(zhuǎn)義,默認(rèn)為默認(rèn)自動(dòng)轉(zhuǎn)義
    bt.ESCAPE = true;

    //HTML轉(zhuǎn)義
    bt._encodeHTML = function (source) {
    return String(source)
    .replace(/&/g,'&')
    .replace(/</g,'<')
    .replace(/>/g,'>')
    .replace(/\/g,'\')
    .replace(/"/g,'"')
    .replace(/'/g,''');
    };
    //轉(zhuǎn)義影響正則的字符
    bt._encodeReg = function (source) {
    return String(source).replace(/([.*+?^=!{}()|[]/\])/g,'\$1');
    };

    //轉(zhuǎn)義UI UI變量使用在HTML頁(yè)面標(biāo)簽onclick等事件函數(shù)參數(shù)中
    bt._encodeEventHTML = function (source) {
    return String(source)
    .replace(/&/g,'&')
    .replace(/</g,'<')
    .replace(/>/g,'>')
    .replace(/"/g,'"')
    .replace(/'/g,''')
    .replace(/\\/g,'\')
    .replace(/\//g,'/')
    .replace(/\n/g,'\n')
    .replace(/\r/g,'\r');
    };

    //將字符串拼接生成函數(shù),即編譯過程(compile)
    bt._compile = function(str){
    var funBody = "var _template_fun_array=[];\nvar fn=(function(data){\nvar _template_varName='';\nfor(name in data){\n_template_varName+=('var '+name+'=data["'+name+'"];');\n};\neval(_template_varName);\n_template_fun_array.push('"+bt._analysisStr(str)+"');\n_template_varName=null;\n})(_template_object);\nfn = null;\nreturn _template_fun_array.join('');\n";
    return new Function("_template_object",funBody);
    };

    //判斷是否是Object類型
    bt._isObject = function (source) {
    return 'function' === typeof source || !!(source && 'object' === typeof source);
    };

    //解析模板字符串
    bt._analysisStr = function(str){

      //取得分隔符
      var _left_ = bt.LEFT_DELIMITER;
      var _right_ = bt.RIGHT_DELIMITER;
    
      //對(duì)分隔符進(jìn)行轉(zhuǎn)義,支持正則中的元字符,可以是HTML注釋 <!  !>
      var _left = bt._encodeReg(_left_);
      var _right = bt._encodeReg(_right_);
    
      str = String(str)
          
          //去掉分隔符中js注釋
          .replace(new RegExp("("+_left+"[^"+_right+"]*)//.*\n","g"), "$1")
          //去掉注釋內(nèi)容  <%* 這里可以任意的注釋 *%>
          //默認(rèn)支持HTML注釋,將HTML注釋匹配掉的原因是用戶有可能用 <! !>來做分割符
          .replace(new RegExp("<!--.*?-->", "g"),"")
          .replace(new RegExp(_left+"\\*.*?\\*"+_right, "g"),"")
    
          //把所有換行去掉  \r回車符 \t制表符 \n換行符
          .replace(new RegExp("[\\r\\t\\n]","g"), "")
    
          //用來處理非分隔符內(nèi)部的內(nèi)容中含有 斜杠 \ 單引號(hào) ‘ ,處理辦法為HTML轉(zhuǎn)義
          .replace(new RegExp(_left+"(??!"+_right+")[\\s\\S])*"+_right+"|((??!"+_left+")[\\s\\S])+)","g"),function (item, $1) {
              var str = '';
              if($1){
    
                  //將 斜杠 單引 HTML轉(zhuǎn)義
                  str = $1.replace(/\\/g,"&#92;").replace(/'/g,'&#39;');
                  while(/<[^<]*?&#39;[^<]*?>/g.test(str)){
    
                      //將標(biāo)簽內(nèi)的單引號(hào)轉(zhuǎn)義為\r  結(jié)合最后一步,替換為\'
                      str = str.replace(/(<[^<]*?)&#39;([^<]*?>)/g,'$1\r$2')
                  };
              }else{
                  str = item;
              }
              return str ;
          });
          str = str 
          //定義變量,如果沒有分號(hào),需要容錯(cuò)  <%var val='test'%>
          .replace(new RegExp("("+_left+"[\\s]*?var[\\s]*?.*?[\\s]*?[^;])[\\s]*?"+_right,"g"),"$1;"+_right_)
    
          //對(duì)變量后面的分號(hào)做容錯(cuò)(包括轉(zhuǎn)義模式 如<%:h=value%>)  <%=value;%> 排除掉函數(shù)的情況 <%fun1();%> 排除定義變量情況  <%var val='test';%>
          .replace(new RegExp("("+_left+":?[hvu]?[\\s]*?=[\\s]*?[^;|"+_right+"]*?);[\\s]*?"+_right,"g"),"$1"+_right_)
    
          //按照 <% 分割為一個(gè)個(gè)數(shù)組,再用 \t 和在一起,相當(dāng)于將 <% 替換為 \t
          //將模板按照<%分為一段一段的,再在每段的結(jié)尾加入 \t,即用 \t 將每個(gè)模板片段前面分隔開
          .split(_left_).join("\t");
    
      //支持用戶配置默認(rèn)是否自動(dòng)轉(zhuǎn)義
      if(bt.ESCAPE){
          str = str
    
              //找到 \t=任意一個(gè)字符%> 替換為 ‘,任意字符,'
              //即替換簡(jiǎn)單變量  \t=data%> 替換為 ',data,'
              //默認(rèn)HTML轉(zhuǎn)義  也支持HTML轉(zhuǎn)義寫法<%:h=value%>  
              .replace(new RegExp("\\t=(.*?)"+_right,"g"),"',typeof($1) === 'undefined'?'':baidu.template._encodeHTML($1),'");
      }else{
      str = str
              
              //默認(rèn)不轉(zhuǎn)義HTML轉(zhuǎn)義
              .replace(new RegExp("\\t=(.*?)"+_right,"g"),"',typeof($1) === 'undefined'?''1,'");
      };
    
      str = str
    
          //支持HTML轉(zhuǎn)義寫法<%:h=value%>  
          .replace(new RegExp("\\t:h=(.*?)"+_right,"g"),"',typeof($1) === 'undefined'?'':baidu.template._encodeHTML($1),'")
    
          //支持不轉(zhuǎn)義寫法 <%:=value%>和<%-value%>
          .replace(new RegExp("\\t(?::=|-)(.*?)"+_right,"g"),"',typeof($1)==='undefined'?''1,'")
    
          //支持url轉(zhuǎn)義 <%:u=value%>
          .replace(new RegExp("\\t:u=(.*?)"+_right,"g"),"',typeof($1)==='undefined'?'':encodeURIComponent($1),'")
    
          //支持UI 變量使用在HTML頁(yè)面標(biāo)簽onclick等事件函數(shù)參數(shù)中  <%:v=value%>
          .replace(new RegExp("\\t:v=(.*?)"+_right,"g"),"',typeof($1)==='undefined'?'':baidu.template._encodeEventHTML($1),'")
    
          //將字符串按照 \t 分成為數(shù)組,在用'); 將其合并,即替換掉結(jié)尾的 \t 為 ');
          //在if,for等語(yǔ)句前面加上 '); ,形成 ');if  ');for  的形式
          .split("\t").join("');")
    
          //將 %> 替換為_template_fun_array.push('
          //即去掉結(jié)尾符,生成函數(shù)中的push方法
          //如:if(list.length=5){%><h2>',list[4],'</h2>');}
          //會(huì)被替換為 if(list.length=5){_template_fun_array.push('<h2>',list[4],'</h2>');}
          .split(_right_).join("_template_fun_array.push('")
    
          //將 \r 替換為 \
          .split("\r").join("\\'");
    
      return str;
    

    };

})(window);

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 我們通過ajax請(qǐng)求或者是通過jsonp請(qǐng)求來獲取服務(wù)器回傳的數(shù)據(jù),但是文件類型,有兩種方式,一是:xml文件類型...
    風(fēng)清揚(yáng)101閱讀 400評(píng)論 0 0
  • 百度模板主要分為兩大部分 第一部分選區(qū)模板 選區(qū)模板baidu.template(str,data)參數(shù)str為選...
    小a草閱讀 511評(píng)論 0 0
  • JS引擎模板 baiduTeplate 模板語(yǔ)法 提供一套模板語(yǔ)法,用戶可以定義一個(gè)模板區(qū)塊,每次根據(jù)傳入的數(shù)據(jù)生...
    立早人青小超人閱讀 3,859評(píng)論 1 4
  • 《ijs》速成開發(fā)手冊(cè)3.0 官方用戶交流:iApp開發(fā)交流(1) 239547050iApp開發(fā)交流(2) 10...
    葉染柒丶閱讀 5,622評(píng)論 0 7
  • 一 莫小兮也不知道自己中了什么邪,自己竟然在畫室呆了一個(gè)上午。平時(shí)的她對(duì)這些所謂的技巧可是不屑一顧的,而現(xiàn)在她卻在...
    相思蔓上心頭閱讀 452評(píng)論 0 0

友情鏈接更多精彩內(nèi)容