之前在一個項目的時候,很多頁面需要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;//函數返回值
}
再次感謝這位朋友,讓我認識到前后端分離,框架,模塊化管理。共勉!!
