美文网首页
javascript 高级 -- 模板

javascript 高级 -- 模板

作者: 风清扬101 | 来源:发表于2017-05-14 09:34 被阅读0次

    我们通过ajax请求或者是通过jsonp请求来获取服务器回传的数据,但是文件类型,有两种方式,一是:xml文件类型。二是:json文件类型。我们可以通过DOM节点来解析,拼接到页面中。创建符合语义化语言的标签。赋值,再通过appenChind()来添加到页面中,我们在解析复杂的数据类型时,这种方式比较复杂。所以,我们可以利用好模板的特性来简化我们解析的数据,再往页面添加数据的工作。

    我们可以下载大神们封装好的模板来进行引用,我以百度的模板来进行操作。具体源码如下:

    ;(function(window){    //取得浏览器环境的baidu命名空间,非浏览器环境符合commonjs规范exports出去    //修正在nodejs环境下,采用baidu.template变量名    var baidu = typeof module === 'undefined' ? (window.baidu = window.baidu || {}) : module.exports;    //模板函数(放置于baidu.template命名空间下)    baidu.template = function(str, data){        //检查是否有该id的元素存在,如果有元素则获取元素的innerHTML/value,否则认为字符串为模板        var fn = (function(){            //判断如果没有document,则为非浏览器环境            if(!window.document){                return bt._compile(str);            };            //HTML5规定ID可以由任何不包含空格字符的字符串组成            var element = document.getElementById(str);            if (element) {                                    //取到对应id的dom,缓存其编译后的HTML模板函数                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{                //是模板字符串,则生成一个函数                //如果直接传入字符串作为模板,则可能变化过多,因此不考虑缓存                return bt._compile(str);            };        })();        //有数据则返回HTML字符串,没有数据则返回函数 支持data={}的情况        var result = bt._isObject(data) ? fn( data ) : fn;        fn = null;        return result;    };    //取得命名空间 baidu.template    var bt = baidu.template;    //标记当前版本    bt.versions = bt.versions || [];    bt.versions.push('1.0.6');    //缓存  将对应id模板生成的函数缓存下来。    bt.cache = {};        //自定义分隔符,可以含有正则中的字符,可以是HTML注释开头bt.LEFT_DELIMITER = bt.LEFT_DELIMITER||'<%';    bt.RIGHT_DELIMITER = bt.RIGHT_DELIMITER||'%>';    //自定义默认是否转义,默认为默认自动转义    bt.ESCAPE = true;    //HTML转义    bt._encodeHTML = function (source) {        return String(source)            .replace(/&/g,'&')            .replace(//g,'>')            .replace(/\\/g,'\')            .replace(/"/g,'"')            .replace(/'/g,''');    };    //转义影响正则的字符    bt._encodeReg = function (source) {        return String(source).replace(/([.*+?^=!:${}()|[\]/\\])/g,'\\$1');    };    //转义UI UI变量使用在HTML页面标签onclick等事件函数参数中    bt._encodeEventHTML = function (source) {        return String(source)            .replace(/&/g,'&')            .replace(//g,'>')            .replace(/"/g,'"')            .replace(/'/g,''')            .replace(/\\\\/g,'\\')            .replace(/\\\//g,'\/')            .replace(/\\n/g,'\n')            .replace(/\\r/g,'\r');    };    //将字符串拼接生成函数,即编译过程(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;        //对分隔符进行转义,支持正则中的元字符,可以是HTML注释var _left = bt._encodeReg(_left_);        var _right = bt._encodeReg(_right_);        str = String(str)                        //去掉分隔符中js注释            .replace(new RegExp("("+_left+"[^"+_right+"]*)//.*\n","g"), "$1")            //去掉注释内容  <%* 这里可以任意的注释 *%>            //默认支持HTML注释,将HTML注释匹配掉的原因是用户有可能用来做分割符            .replace(new RegExp("", "g"),"")            .replace(new RegExp(_left+"\\*.*?\\*"+_right, "g"),"")            //把所有换行去掉  \r回车符 \t制表符 \n换行符            .replace(new RegExp("[\\r\\t\\n]","g"), "")            //用来处理非分隔符内部的内容中含有 斜杠 \ 单引号 ‘ ,处理办法为HTML转义            .replace(new RegExp(_left+"(?:(?!"+_right+")[\\s\\S])*"+_right+"|((?:(?!"+_left+")[\\s\\S])+)","g"),function (item, $1) {                var str = '';                if($1){                    //将 斜杠 单引 HTML转义                    str = $1.replace(/\\/g,"\").replace(/'/g,''');                    while(/<[^<]*?'[^<]*?>/g.test(str)){                        //将标签内的单引号转义为\r  结合最后一步,替换为\'                        str = str.replace(/(<[^<]*?)'([^<]*?>)/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_)            //对变量后面的分号做容错(包括转义模式 如<%:h=value%>)  <%=value;%> 排除掉函数的情况 <%fun1();%> 排除定义变量情况  <%var val='test';%>            .replace(new RegExp("("+_left+":?[hvu]?[\\s]*?=[\\s]*?[^;|"+_right+"]*?);[\\s]*?"+_right,"g"),"$1"+_right_)            //按照 <% 分割为一个个数组,再用 \t 和在一起,相当于将 <% 替换为 \t            //将模板按照<%分为一段一段的,再在每段的结尾加入 \t,即用 \t 将每个模板片段前面分隔开            .split(_left_).join("\t");        //支持用户配置默认是否自动转义        if(bt.ESCAPE){            str = str                //找到 \t=任意一个字符%> 替换为 ‘,任意字符,'                //即替换简单变量  \t=data%> 替换为 ',data,'                //默认HTML转义  也支持HTML转义写法<%:h=value%>                  .replace(new RegExp("\\t=(.*?)"+_right,"g"),"',typeof($1) === 'undefined'?'':baidu.template._encodeHTML($1),'");        }else{            str = str                                //默认不转义HTML转义                .replace(new RegExp("\\t=(.*?)"+_right,"g"),"',typeof($1) === 'undefined'?'':$1,'");        };        str = str            //支持HTML转义写法<%:h=value%>              .replace(new RegExp("\\t:h=(.*?)"+_right,"g"),"',typeof($1) === 'undefined'?'':baidu.template._encodeHTML($1),'")            //支持不转义写法 <%:=value%>和<%-value%>            .replace(new RegExp("\\t(?::=|-)(.*?)"+_right,"g"),"',typeof($1)==='undefined'?'':$1,'")            //支持url转义 <%:u=value%>            .replace(new RegExp("\\t:u=(.*?)"+_right,"g"),"',typeof($1)==='undefined'?'':encodeURIComponent($1),'")            //支持UI 变量使用在HTML页面标签onclick等事件函数参数中  <%:v=value%>            .replace(new RegExp("\\t:v=(.*?)"+_right,"g"),"',typeof($1)==='undefined'?'':baidu.template._encodeEventHTML($1),'")            //将字符串按照 \t 分成为数组,在用'); 将其合并,即替换掉结尾的 \t 为 ');            //在if,for等语句前面加上 '); ,形成 ');if  ');for  的形式            .split("\t").join("');")            //将 %> 替换为_template_fun_array.push('            //即去掉结尾符,生成函数中的push方法            //如:if(list.length=5){%>

    ',list[4],'

    ');}            //会被替换为 if(list.length=5){_template_fun_array.push('

    ',list[4],'

    ');}            .split(_right_).join("_template_fun_array.push('")            //将 \r 替换为 \            .split("\r").join("\\'");        return str;    };})(window);

    下一步,我们怎么利用模板呢?

    第一步是:我们用script标签来引入我们的封装好的模板文件。

    第二步:我们在bady里定义我们的模板内容,称为定义模板。用script标签来创建,而类型 type = "text/html"或者是 type="text/tempale" 。然后,我们需要加上id,以备我们在用百度模板时能调用到。 我们在模板里面操作的话,要注意是语法。在百度模板里,我们用的是<%%>形式来解析标签。我们可以在模板里面直接设置我们需要的接受数据的标签。然后用自定义标签<%=属性%> 就可以赋值给我们自定义的标签,注意:我们的自定义的标签不能写在<%%>里面,不然,会把我们接受数据的自定义的标签当成属性。导致语法错误!所以,我们遍历数组时,要注意我们的大括号的包含。用<%%>来包裹里面。

    还有,我们要注意的是,我们要的对象的属性。用注意的是文件格式,要转化为对象格式。然后再用模板的语法解析。直接把对象传进来,可以解析对象下的属性。

    第三步:我们在script标签里面再回调百度模板函数。定义一个变量来接受解析的数据。例如:

    var html0 = baidu.template("定义的模板id值",数据对象);

    document.querySeletor("页面的标签").innerHTML=html0

    这就可以来解析了,显示页面了。

    这是我们的模板的妙用。

    相关文章

      网友评论

          本文标题:javascript 高级 -- 模板

          本文链接:https://www.haomeiwen.com/subject/jcyazttx.html