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

    ejsv8对ejsv7进行大量简化与提速工作,本版本进行了以下改进。

    • 去掉去掉参数多态化,现在只有两个参数。第一个参数为script标签的ID,第二个参数对数据对象
    • 去掉@标识符,网友反映这东西很怪
    • 去掉远程模板支持,因为怎么远程也一定要同域才行,要不AJAX获取不到,鸡肋。以后模板统一写到type为"text/html"的scrpt元素中。
    • 优化quote函数。网上有许多JS模板都是直接用正则进行全文转义,但怎么说也不比上quote函数安全。
    • 使用apply对传参进行优化。indexOf判定优化。
    • 代码量由140行缩减到75行。
          //dom.ejs v8 by 司徒正美
          //http://www.cnblogs.com/rubylouvre/archive/2011/03/03/1969718.html
          ;
          (function(DOC){
            this.dom = {
              quote :  window.JSON && JSON.stringify || 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, '\\"') + '"';
              }
    
            }
            if(!String.prototype.trim){
              String.prototype.trim = function(){
                return this.replace(/^[\s\xa0]+|[\s\xa0]+$/g, '');
              }
            }
            var
            metaObject = {
              '\b': '\\b',
              '\t': '\\t',
              '\n': '\\n',
              '\f': '\\f',
              '\r': '\\r',
              '\\': '\\\\'
            },
            _startOfHTML = "\t__views.push(",
            _endOfHTML = ");\n",
            sRight = "&>",
            rLeft = /\s*<&\s*/,
            rRight = /\s*&>\s*/
            var ejs2 = dom.ejs = function(id,data){
              if(!ejs2[id]){
                var rleft = rLeft, rright = rRight, sright = sRight,startOfHTML = _startOfHTML, endOfHTML = _endOfHTML, str , logic,
                el = DOC.getElementById(id);
                if (!el) throw "can not find the target element";
                str = el.text;
                var arr = str.trim().split(rleft),
                temp = ["var __views = [];\n"],i = 0,n = arr.length,els,segment;
                while(i < n){//逐行分析,以防歧义
                  segment = arr[i++];
                  els = segment.split(rright);
                  if(~segment.indexOf(sright) ){//这里不使用els.length === 2是为了避开IE的split bug
                    switch (els[0].charAt(0)) {
                      case "="://处理后台返回的变量(输出到页面的);
                        logic = els[0].substring(1);
                        temp.push(startOfHTML, logic, endOfHTML);
                        break;
                      case "#"://处理注释
                        break;
                      default://处理逻辑
                        logic = els[0];
                        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);
                  }
                }
                var keys = [], values = [];
                for( i in data){
                  keys.push(i);
                  values.push(data[i]);
                }
                keys.push(temp.concat(" return __views.join('');").join(""))
                return (ejs2[id] = Function.apply(0,keys)).apply(0,values);
              }
              var vals = []
              for( i in data){
                vals.push(data[i]);
              }
              return ejs2[id].apply(0,vals);
            }
          })(document);
    

    用法var str = dom.ejs(id,data)。第一个参数为script标签的ID,第二个参数对数据对象。str为处理好的HTML片断字符,直接el.innerHTML = str就行。界定符依旧是<&与>&,如果<紧跟着的是=号,说明这后面的部要输出页面,若是#号,则是注释,不输出页面,其他部分与ASP的使用方法一样。

    下面是与糖饼的tmplv2,公认最快的模板YayaTemplate,ejsv7的速度比较,为了公平起见,ejsv7,v8都去掉缓存功能。

    糖饼与yaya的都是模仿jQ作者John Resig 的思路,通过环则反复对界定符进行替换,对HTML部分进行转义,但我不相信那一点正则完全实现转义,可以正则构建的代码结构也缺乏对各种特殊情况的处理,要不John Resig就不会搞一个更长更庞大的jquery-tmpl。比如yaya的如果第一行是{% list[0].index%}就报错了,可证一个。如果页面结构更复杂一点,其缺陷就暴露得更多。

    更新日志

    
    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天生支持模板的相互调用便去除<&:与<&~操作符
    
    v8
    
    简化与提速
    
                tmpl02    ejsv7    ejsv8    yaya
    
    opera11.52  271.9     258.65  253      200.45
    chrome14    380.6     373.85  367.95   402.05
    firefox7.01 235.7     166.2   174.25   151.5
    IE9         432.25    489.6   468.5    394.1
    safari 5    332.35    292.45  292.05   265.15
    
  • 相关阅读:
    angular2学习
    随笔
    angular 中ng-repeat后ng-click失效
    一个hover效果
    获取屏幕高度
    延时加载 lazyload使用技巧
    关于MVC模板渲染的一点小事type="text/template"
    JsRender实用教程(tag else使用、循环嵌套访问父级数据)
    jQuery Validate 插件为表单提供了强大的验证功能
    日期时间选择器bootstrap-datetimepicker表单组件
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/2221295.html
Copyright © 2011-2022 走看看