javascript 高级 -- 模板

我们通过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

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

这是我们的模板的妙用。

最后编辑于
?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,128评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,316评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事?!?“怎么了?”我有些...
    开封第一讲书人阅读 159,737评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,283评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,384评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,458评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,467评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,251评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,688评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,980评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,155评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,818评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,492评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,142评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,382评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,020评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,044评论 2 352

推荐阅读更多精彩内容