经过1年的磨练,近期终于稍微明白到,前端是怎么做到企业要求的:数据交互.
1,ajax+json这个是必须学的,但没问题,我们可以通过这个博客来慢慢了解怎么回事?
2,可以通过JS框架和JS模板来实现,但最后还是要用到ajax+json的.
注意:个人建议 假如项目页面数量是少于50-100个的,那么推荐使用JS模板;如果大于100个的用JS框架.各有各优势嘛。
今晚的博客分几次写完,看到这句话删除就证明已经写完了。
先分享JS模板的内容:我这次推荐使用百度的模板引擎,因为他比腾讯的art运行速度快1倍.(而且腾讯的模板,我看不懂怎么分情况去做.)
HTML:这个是官方的
<!doctype html> <html> <head> <meta charset="utf-8"/> <title>test</title> <!-- 引入baiduTemplate --> <script type="text/javascript" src="js/template.min.js"></script> </head> <body> <h3>BaiduTemplate单元测试用例</h3> <!-- 测试模板1开始 --> <script id=‘content‘ type="text/template"> <br> 1、基本输出(自动HTML转义): <%=value1%> <br> <br> 2、容错写法: <%=value2;%> <br> <br> 3、不转义输出: <%:=value3%> 或 <%-value3%> <br> <br> 4、容错写法: <%:=value4;%> <br> <br> 5、URL转义输出: <%:u=value5%> <br> <br> 6、容错写法: <%:u=value6;%> <br> <br> 7、UI变量在页面标签事件中使用转义: <%:v=value7%> <br> <br> 8、容错写法:<%:v=value8;%> <br> <br> 9、HTML转义输出:<%:h=value9%> <br> <br> 10、容错写法:<%:h=value10;%> <br> <br> 11、变量未定义自动输出空:<%=value11%> <br> <br> 12、模板直接输出特殊字符:5个斜杠 ///// 5个单引 ‘’‘’‘ 5个双引 “”“”“ <br> <br> 13、注释: <!-- HTML注释支持 --> <%* 模板自带注释 *%> <% //js注释方式 %> <br> <br> 14、判断语句: <%if(value14){%> <input type="text" value="<%:v=value14%>"/> <%}else{%> 无值 <%}%> <br> <br> 15、循环语句: <br> <ul> <%for(var i=0;i<value17.length;i++){%> <li><%=value17[i]%></li> <%}%> </ul> <br> <br> 16、a标签 <br> 单引问题:<a target=‘_blank‘ href=‘http://www.baidu.com ‘ onclick=‘alert("test");‘>test</a><br> 双引问题:<a target="_blank" href="http://www.baidu.com" onclick="alert(‘test‘);">test</a><br> 17、定义变量: <%var varTest1 = value1%> varTest1: <%=varTest1;%> <br> 18、定义变量容错: <%var varTest2 = value2;%> varTest2: <%=varTest2%> <br> </script> <!-- 测试模板1结束 --> <div id="results"></div> <script type="text/javascript"> window.onload=function(){ //测试数据,对应每个用例 var data={ value1:‘<span style="color:red;">http://wangxiao.github.com/BaiduTemplate/</span>‘, value2:‘<span style="color:red;">http://wangxiao.github.com/BaiduTemplate/</span>‘, value3:‘<span style="color:red;">http://wangxiao.github.com/BaiduTemplate/</span>‘, value4:‘<span style="color:red;">http://wangxiao.github.com/BaiduTemplate/</span>‘, value5:‘<span style="color:red;">http://wangxiao.github.com/BaiduTemplate/</span>‘, value6:‘<span style="color:red;">http://wangxiao.github.com/BaiduTemplate/</span>‘, value7:‘<span style="color:red;">http://wangxiao.github.com/BaiduTemplate/</span><span style="color:red;">\\\‘\"</span>‘, value8:‘<span style="color:red;">http://wangxiao.github.com/BaiduTemplate/</span><span style="color:red;">\\\‘\"</span>‘, value9:‘<span style="color:red;">http://wangxiao.github.com/BaiduTemplate/</span>‘, value10:‘<span style="color:red;">http://wangxiao.github.com/BaiduTemplate/</span>‘, value14:‘<span style="color:red;">http://wangxiao.github.com/BaiduTemplate/</span>‘, value15:‘<span style="color:red;">http://wangxiao.github.com/BaiduTemplate/</span>‘, value16:[‘<span style="color:red;">这是value</span>‘,123,‘<span style="color:red;">http://wangxiao.github.com/BaiduTemplate/</span>‘], value17:[‘<span style="color:red;">这是value</span>‘,123,‘<span style="color:red;">http://wangxiao.github.com/BaiduTemplate/</span>‘] }; //使用 var bat=baidu.template; //设置分隔符 //bat.LEFT_DELIMITER=‘<!‘; //bat.RIGHT_DELIMITER=‘!>‘; //设置默认是否转义 //bat.ESCAPE = false; var timestart = new Date().getTime(); //输出函数 var fun=bat(‘content‘); var timeend = new Date().getTime(); alert(‘最大话编译一次时间:‘+(timeend-timestart)+‘毫秒‘); timestart = new Date().getTime(); //输出HTML var html=bat(‘content‘,data); timeend = new Date().getTime(); alert(‘运行时间:‘+(timeend-timestart)+‘毫秒‘); //显示结果 document.getElementById(‘results‘).innerHTML=html; } </script> </body> </html>
官方的JS代码:有心学习的,还是要认真看看里面的注释!
/** * 特性: 1、语法简单,学习成本极低,开发效率提升很大,性价比较高(使用Javascript原生语法); 2、默认HTML转义(防XSS攻击),并且支持包括URL转义等多种转义; 3、变量未定义自动输出为空,防止页面错乱; 4、功能强大,如分隔符可自定等多种功能; */ ;(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,‘"‘) .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(/\\\//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){%><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);
我压缩后的代码:
;(function(window){var baidu=typeof module==="undefined"?(window.baidu=window.baidu||{}):module.exports; //模板函数(放置于baidu.template命名空间下) baidu.template=function(str,data){var fn=(function(){if(!window.document){return bt._compile(str)}var element=document.getElementById(str);if(element){if(bt.cache[str]){return bt.cache[str]}var html=/^(textarea|input)$/i.test(element.nodeName)?element.value:element.innerHTML;return bt._compile(html)}else{return bt._compile(str)}})();var result=bt._isObject(data)?fn(data):fn;fn=null;return result}; var bt=baidu.template;//取得命名空间 baidu.template bt.versions=bt.versions||[];bt.versions.push("1.0.6");bt.cache={}; //自定义分隔符,可以含有正则中的字符,可以是HTML注释开头 <! !> bt.LEFT_DELIMITER=bt.LEFT_DELIMITER||"<%";bt.RIGHT_DELIMITER=bt.RIGHT_DELIMITER||"%>"; bt.ESCAPE=true;bt._encodeHTML=function(source){return String(source).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/\\/g,"\").replace(/"/g,""").replace(/‘/g,"'")};bt._encodeReg=function(source){return String(source).replace(/([.*+?^=!:${}()|[\]/\\])/g,"\\$1")};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")};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);};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;var _left=bt._encodeReg(_left_);var _right=bt._encodeReg(_right_);str=String(str).replace(new RegExp("("+_left+"[^"+_right+"]*)//.*\n","g"),"$1").replace(new RegExp("<!--.*?-->","g"),"").replace(new RegExp(_left+"\\*.*?\\*"+_right,"g"),"").replace(new RegExp("[\\r\\t\\n]","g"),"").replace(new RegExp(_left+"(?:(?!"+_right+")[\\s\\S])*"+_right+"|((?:(?!"+_left+")[\\s\\S])+)","g"),function(item,$1){var str="";if($1){str=$1.replace(/\\/g,"\").replace(/‘/g,"'");while(/<[^<]*?'[^<]*?>/g.test(str)){str=str.replace(/(<[^<]*?)'([^<]*?>)/g,"$1\r$2")}}else{str=item}return str});str=str.replace(new RegExp("("+_left+"[\\s]*?var[\\s]*?.*?[\\s]*?[^;])[\\s]*?"+_right,"g"),"$1;"+_right_).replace(new RegExp("("+_left+":?[hvu]?[\\s]*?=[\\s]*?[^;|"+_right+"]*?);[\\s]*?"+_right,"g"),"$1"+_right_).split(_left_).join("\t");if(bt.ESCAPE){str=str.replace(new RegExp("\\t=(.*?)"+_right,"g"),"‘,typeof($1) === ‘undefined‘?‘‘:baidu.template._encodeHTML($1),‘")}else{str=str.replace(new RegExp("\\t=(.*?)"+_right,"g"),"‘,typeof($1) === ‘undefined‘?‘‘:$1,‘")}str=str.replace(new RegExp("\\t:h=(.*?)"+_right,"g"),"‘,typeof($1) === ‘undefined‘?‘‘:baidu.template._encodeHTML($1),‘").replace(new RegExp("\\t(?::=|-)(.*?)"+_right,"g"),"‘,typeof($1)===‘undefined‘?‘‘:$1,‘").replace(new RegExp("\\t:u=(.*?)"+_right,"g"),"‘,typeof($1)===‘undefined‘?‘‘:encodeURIComponent($1),‘").replace(new RegExp("\\t:v=(.*?)"+_right,"g"),"‘,typeof($1)===‘undefined‘?‘‘:baidu.template._encodeEventHTML($1),‘").split("\t").join("‘);").split(_right_).join("_template_fun_array.push(‘").split("\r").join("\\‘");return str};})(window);
今天我发现,如果你直接拿官方的来去压缩,有可能会出错,因为网上不是所有的JS压缩工具都会帮你做好,
同时你有可能会发现,压缩前跟压缩后运行的时间并不一样,压缩后的代码可能会经常性的慢2-5毫秒不等.
原因:JavaScript处理的HTML的内容,其实我们应该压缩的是html,而不是JS.
那么我们为什么习惯性或者道听途说的遇到这样就压缩JS文件呢?那是为了后端.
你所不知道的是对于大型项目来说,10KB可以让你的公司每年节省不少费用.
所以,前端需要压缩的文件有html,css,js,img,对就是全部文件都得压缩,当然了,img得分情况,不然压缩后会失真.
好了,现在分享下我对模板引擎的一些使用分享:
<!DOCTYPE html> <html> <head> <title>百度JS模板引擎</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <meta http-equiv="Pragma" name="no-store" /> <meta http-equiv="Cache-Control" name="no-store" /> <meta http-equiv="window-target" content="_top" /> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> <meta name="HandheldFriendly" content="true" /> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta content="telephone=no" name="format-detection" /> <meta name="renderer" content="webkit"> <meta name="msapplication-tap-highlight" content="no"> <script type="text/javascript" src="js/template.min.js"></script> <style> li{list-style:none;} </style> </head> <body> <!-- 模板开始 --> <script id=‘content‘ type="text/html"> <h1><%=title%></h1> <ul> <!-- 循环语句 for--> <%for(var i=0,len=list.length;i<len;i++){%> <li> <%=list[i]%> </li> <%}%> </ul> <!-- 判断语句if else;是用来dom判断选择的--> <%var j=0%> <%if(select.length>1) { %> <h2>select,共有<%=select.length%>个元素</h2> <ul> <li> <%=select[j]%> </li> <!-- <%for(var j=0,len=select.length;j<len;j++){%> <li><%=select[j]%></li> <%}%> --> </ul> <%} else{%> <h2>select没数据</h2> <%}%> <p><%=footer%></p> </script> <!-- 模板结束 --> <div id="results"></div> <script type="text/javascript"> var data = { title: "百度JS模板引擎--数据交互的学习", list: [ "这里使用的是for循环", "for循环的作用是用来遍历数据" ], select: [ "if语句的使用是用来dom判断选择的;同时只能输出一个数据", "想把这个给遍历出来吗?那就用for循环" ], footer:"不需要考虑太多,直接用<%=value%>来写你的内容即可" }; //模板调用 var bat = baidu.template; //输出函数 var fun = bat(‘content‘); //输出HTML var html = bat(‘content‘, data); //显示结果 document.getElementById(‘results‘).innerHTML = html; </script> </body> </html>
解释下data里面的数据:
title,list在JS里面可以不加引号的,但在json里面,你必须得加引号.
时间: 2024-10-25 13:26:12