之前在一个项目的时候,很多页面需要AJAX传值来渲染页面,每到这个时候,自己也觉得很头痛,因为每次渲染的时候,都使用的是把HTML代码拼接上去,一代代码量大了,很容易出错,还有就是没有易读性,在做完整个项目后,自己也觉得一定会有更好的办法,后来在一个朋友的帮助下,认识总算的到了一个他们使用的方案,让我豁然开朗,不一定是最优解,但是一定比使用HTML拼接更加容易维护更容易让人读懂。我把代码认真的读了几次,几乎把每一行都注释了,也写出了自己的疑问,希望大神解答。
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus®"> <meta name="Author" content=""> <meta name="Keywords" content=""> <meta name="Description" content=""> <script type="text/javascript" src="jquery.js"></script> <title>Document</title> </head> <body> <!--非循环--> <div id="container" class=""> <p>$[name]</p> <p>$[age]</p> <p>$[salary]</p> </div> <!--循环--> <!--模板 (不显示)--> <div id="template" style="display:none"> <div> $[name]<br/> $[title] </div> </div> <div id="container1" class=""> </div> <a id="more">点击加载更多</a> </body> </html> <script type="text/javascript"> var json = { name:'test', age:15, salary:5500 } //不循环绑定数据的话就直接指定容器 replaceElementInnerText($('#container'),json) var json1 = { name : "这是循环的结果", title:"这是循环结果2" } $('#more').click(function(){ var json2 = [{name:'name测试1',title:'title测试1'},{name:'name测试2',title:'title测试2'},{name:'name测试3',title:'title测试3'}] var temp = $('#template').children().prop('outerHTML');//获取template的子元素的HTML(包括自身) for(var i = 0;i <3;i++){//确定需要生成新模板的循环 var $temp = $(temp);//把模板转换为JQ对象 replaceElementInnerText($temp,json2[i]); $('#container1').append($temp); } }) //替换函数 function replaceElementInnerText (ele, data) { var $ele,innerHTML;//创建两个变量 if(typeof ele == 'string'){//判断ele是否为对象还是字符串,是字符串就再次转换为对象 $ele=$(ele); innerHTML=$ele.html();//然后调出此对象的HTML }else{//如果是对象 $ele=(ele instanceof jQuery)?ele:$(ele);//就判断ele的实例对象是否为jq如果不是则转换为jq对象 innerHTML=$ele.html();//得到此对象的HTML } var pattern=/\$\[(\w+\.*\w*)]/g;//正则式,根据自己规则来编写 var replace_attr=[];//创建一个空数组,用来装即将匹配的文本 var i=0; while(i++<100) { var result = pattern.exec(innerHTML);//把innerHTML放入正则式去搜索 if (!result) {//如果搜索不到,循环结束 break; } replace_attr.push(result[1]);//把搜索到的文本添加到预先准备的数组里 } for(var key in replace_attr){//给数组循环 var replace=new RegExp('\\$\\['+replace_attr[key]+'\\]','g');//创建一个正则式 if(replace_attr[key].indexOf(".")>0){//如果当前名字里有.去掉点,拆分为数组(注:这里自己感觉太累赘,可能我哪里没有想到) var replace_attr_keys=replace_attr[key].split("."); var replace_attr_str="data";//创建一个字符串,用于后面的拼接 if(!data[replace_attr_keys[0]]||typeof data[replace_attr_keys[0]]!=='object'){ continue; } for(var _key in replace_attr_keys){//循环拆分出来的数组 replace_attr_str+='[\''+replace_attr_keys[_key]+'\']';//拼接拆分猪来的数组 } if(eval(replace_attr_str)!=null){ innerHTML=innerHTML.replace(replace,eval(replace_attr_str));//把值替换为后台服务器传值 } }else{ if(data[replace_attr[key]]!=null){ innerHTML=innerHTML.replace(replace,data[replace_attr[key]]);//把值替换 } } } $ele[0].innerHTML=innerHTML; /* $ele.find('img[img-load="load"]').each(function () { var reg=new RegExp("(http|ftp|https):\/\/w*"); if(reg.exec($(this).attr('_src'))){ $(this).attr("src",$(this).attr('_src')); } });图片替换原理相同,这里没有图片所以注释*/ return $ele[0].outerHTML;//函数返回值 }
再次感谢这位朋友,让我认识到前后端分离,框架,模块化管理。共勉!!