baiduTemplate

/**

  • baiduTemplate簡單好用的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對象卓研,可以為空。當(dāng)data為{}時磨淌,仍然返回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) {
          //取到對應(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{
    
              //是模板字符串,則生成一個函數(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');

    //緩存 將對應(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)自動轉(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頁面標(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;
    
      //對分隔符進(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)容中含有 斜杠 \ 單引號 ‘ 明刷,處理辦法為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)的單引號轉(zhuǎn)義為\r  結(jié)合最后一步轰枝,替換為\'
                      str = str.replace(/(<[^<]*?)&#39;([^<]*?>)/g,'$1\r$2')
                  };
              }else{
                  str = item;
              }
              return str ;
          });
          str = str 
          //定義變量键闺,如果沒有分號,需要容錯  <%var val='test'%>
          .replace(new RegExp("("+_left+"[\\s]*?var[\\s]*?.*?[\\s]*?[^;])[\\s]*?"+_right,"g"),"$1;"+_right_)
    
          //對變量后面的分號做容錯(包括轉(zhuǎn)義模式 如<%:h=value%>)  <%=value;%> 排除掉函數(shù)的情況 <%fun1();%> 排除定義變量情況  <%var val='test';%>
          .replace(new RegExp("("+_left+":?[hvu]?[\\s]*?=[\\s]*?[^;|"+_right+"]*?);[\\s]*?"+_right,"g"),"$1"+_right_)
    
          //按照 <% 分割為一個個數(shù)組,再用 \t 和在一起莹汤,相當(dāng)于將 <% 替換為 \t
          //將模板按照<%分為一段一段的钞楼,再在每段的結(jié)尾加入 \t,即用 \t 將每個模板片段前面分隔開
          .split(_left_).join("\t");
    
      //支持用戶配置默認(rèn)是否自動轉(zhuǎn)義
      if(bt.ESCAPE){
          str = str
    
              //找到 \t=任意一個字符%> 替換為 ‘嘿辟,任意字符,'
              //即替換簡單變量  \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頁面標(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等語句前面加上 '); 揭措,形成 ');if  ');for  的形式
          .split("\t").join("');")
    
          //將 %> 替換為_template_fun_array.push('
          //即去掉結(jié)尾符充甚,生成函數(shù)中的push方法
          //如:if(list.length=5){%><h2>',list[4],'</h2>');}
          //會被替換為 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)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市旁理,隨后出現(xiàn)的幾起案子沉衣,更是在濱河造成了極大的恐慌厢蒜,老刑警劉巖巷屿,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡僧著,警方通過查閱死者的電腦和手機(jī)世蔗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來朗兵,“玉大人污淋,你說我怎么就攤上這事∮嘁矗” “怎么了寸爆?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我赁豆,道長仅醇,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任魔种,我火速辦了婚禮析二,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘节预。我一直安慰自己叶摄,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布安拟。 她就那樣靜靜地躺著蛤吓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪糠赦。 梳的紋絲不亂的頭發(fā)上会傲,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天,我揣著相機(jī)與錄音愉棱,去河邊找鬼唆铐。 笑死,一個胖子當(dāng)著我的面吹牛奔滑,可吹牛的內(nèi)容都是我干的艾岂。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼朋其,長吁一口氣:“原來是場噩夢啊……” “哼王浴!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起梅猿,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤氓辣,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后袱蚓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體钞啸,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年喇潘,在試婚紗的時候發(fā)現(xiàn)自己被綠了体斩。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡颖低,死狀恐怖絮吵,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情忱屑,我是刑警寧澤蹬敲,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布暇昂,位于F島的核電站,受9級特大地震影響伴嗡,放射性物質(zhì)發(fā)生泄漏急波。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一闹究、第九天 我趴在偏房一處隱蔽的房頂上張望幔崖。 院中可真熱鬧,春花似錦渣淤、人聲如沸赏寇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嗅定。三九已至,卻和暖如春用踩,著一層夾襖步出監(jiān)牢的瞬間渠退,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工脐彩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留碎乃,地道東北人。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓惠奸,卻偏偏與公主長得像梅誓,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子佛南,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容

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