之前在一个项目的时候,很多页面需要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;//函数返回值
}
再次感谢这位朋友,让我认识到前后端分离,框架,模块化管理。共勉!!