难度是对于子循环列表的解析,比第一个实现有更好的解析效果和应用
-----解析代码---
/*
* 调用形式tags.call({sid:'含解析html父级id', endFunc:解析结束执行Func},{listsObj});
* 能够使用注释的位置可以使用注释格式,不能使用时可以使用 @.---photo--@ 来代替 <!---photo-->
* 普通标签标记为 <!---字母或数字.字数-->
* 内置标签 <!--_字母或数字-->,只能用于输出特定属性
* 它们有:
* <!--_i-->:当前数据下标,从1开始;
* ------------------------------
* <!----->html<!----->:表示顶级重复标签,标签对出现;
* <!---.字母数字--->html<!---.字母数字--->:表示子html重复,标签对类型,且对应数据的"字母数字"对象
* this = {} 可以传入startIndex和endIndex,display 真表示模板隐藏了需要显示,visibility真时表示模板不可见需要显示
* firefox 在某种情况下出现二次调用,所以,最好在onload中使用,防止重复解释
*/
CHRD.template = function(lists) {
if (!lists || (Array != lists.constructor) || (arguments.length > 1) || (lists.length < 1)) {//无数据/非一个参数/参数不是数组/数组长度为0,不处理
this.endFunc && this.endFunc();
return;
}
var sid = CHRD.getObj(this.sid);
if (!sid) {
return alert('js解释模板方法必须指定对象id(sid参数),或对象不存在');
}
var html = sid.innerHTML;
if (this.display) {//隐藏的,移除隐藏属性
html = html.replace(/([;'"])\s*display\s*\:\s*none\s*;?/i, "$1");
} else if (this.visibility) {//不可见的,移除不可见属性
html = html.replace(/([;'"])\s*visibility\s*\:\s*hidden\s*;?/i, "$1");
}
var tempL = tempR = '';
var i = html.indexOf('<!----->');//查找顶级左父标签
(i > -1) && (tempL = html.substr(0, i), html = html.substr(i + 8));//截取解析父节html左边,不包含顶级标签
i = html.lastIndexOf('<!----->');//查找顶级右父标签
(i > -1) && (tempR = html.substr(i + 8), html = html.substr(0, i));//截取解析父节html右边
var tagRe = /[@<][\.\!]\-\-\-([^\-]*)\-\-[@>]/;//注释或自定形式,
var cutHtm = function (htm) {//把html分解成对象树
var arrays = [];
var m, sub, l, max = 500;
while ((--max > 0) && (m = tagRe.exec(htm)) ) {//分离标签与普通html:{tag => html}
l = htm.substring(0, m.index);//标签左边htm
htm = htm.substr(m.index + m[0].length);//切掉标签
l.length && arrays.push(l);//得到标签前htm
if ('' == m[1]) {//放了顶级标签,不处理,直接过滤
} else if ('.' == m[1].substr(0,1)) {//是子循环标签
sub = htm.lastIndexOf(m[0]);//查找子循环的结束标签
if (sub > -1) {//只有结束标签才处理
arrays.push( {tag:m[1].substr(1), type:'.', sub:cutHtm(htm.substring(0, sub))} );//取得子标签树
htm = htm.substr(sub + 8 + m[1].length);//8是标签其它部分长度
}
} else if ('_' == m[1].substr(0,1)) {//是内置标签
arrays.push( {tag:m[1].substr(1), type:'_'} );//得到标签前htm
} else {//普通平等标签
arrays.push( {tag:m[1].replace(/\.\d+$/, ''), type:'', len : m[1].replace(/^.+\.(\d+)$/, '$1')} );//得到标签前htm
}
}
arrays.push(htm);//如果有结束
return arrays;
}
html = cutHtm(html);
//console.log(html);
var parse = function(list, htm, li) {//替换一个列表数据
var temp = '', tmp, sub;
for (var ii = 0; ii < htm.length; ii++) {
tmp = htm[ii];
if (tmp.tag) {//标签
switch (tmp.type) {
case '_'://内置标签
switch(tmp.tag) {
case 'i'://编号
temp += li;
break;
default:
;
};
break;
case '.'://子循环
if (!list || !(sub = list[tmp.tag]) || !sub.length || (Array != sub.constructor)) {//数据行为空/行中无子数据/子数据不是数组/数组为空
break;
}
//console.log(sub);console.log(tmp.sub);break;
for (var subI = 0; subI < sub.length; subI++) {//对子数据循环
temp += parse(sub[subI], tmp.sub, subI + 1);
}
break;
case ''://普通标签
list && list[tmp.tag] && (temp += tmp.len > 0 ? CHRD.byteSub(list[tmp.tag], 0, tmp.len, '...') : list[tmp.tag]);//直接补上值,或空白
break;
default:
;
}
} else {//普通html碎片
temp += tmp;
}
}
return temp;
}
var len = this.endIndex || lists.length;
for (i = this.startIndex || 0; i < len; i++) {//生成顶级重复列表
tempL += parse(lists[i], html, i + 1);
}
sid.innerHTML = tempL + tempR;//把解析后替换
this.endFunc && this.endFunc();//处理结束,执行回调
}
CHRD.loadJs = function (src, id) {
var js;
if (! document.body) {
js = '<script src="' + src + '" charset="UTF-8" type="text/javascript"></script' + '>';
id && ('<span id="javascript' + id + '" style="display:none;">' + js + '</span>');
return document.write(js);
} else if (id && (js = CHRD.getObj('javascript' + id))) {
js.innerHTML = jsLink;
return;
}
js = document.createElement('script');
js.src = src;
id && (js.id = id);
js.setAttribute('charset', 'UTF-8');
js.setAttribute('type', 'text/javascript');
js = document.body.appendChild(js);
}//对象转成url参数
CHRD.obj2url = function(obj) {
if (!obj || (obj.constructor != {}.constructor)) {
return '';
}
var a = [];
for (var p in obj) {
a.push('&' + p + '=' + encodeURIComponent(obj[p]));
}
return a.join('');
}------------模板------
<div class="qu_ids tabHPrivateLeBody" id="hotILecturerHtm">
<!----->
<div class="qu_loopd" style="display:none">
<div class="qu_nei">
<ul class="qu_neilu">
<li class="qu_l"><a href="@.---href--@" title="@.---lecturer--@"><img src="@.---photo--@" width=82 height=96 /></a></li>
<li class="qu_r">
<p class="qu_tidx"><!---lecturer--></p>
<p><!---synopsis--></p>
<p><span>擅长领域:</span><!---good--></p>
<p class="phone"><img src="{IMG_PATH}chrd/index/eww_10.gif" align="absmiddle" title="联系电话" /> <!---mobile--></p>
</li>
<div class="clearfloat"></div>
</ul>
<ul class="qu_tued" style="padding-top:0;">
<!---.lists-->
<li><a href="@.---href--@" title="@.---course--@"><!---course.17--></a></li>
<!---.lists-->
</ul>
</div>
</div>
<!----->
<div class="clearfloat"></div>
</div>
------------绑定数据与模板-------
function hotILecturer(lists) {
CHRD.template.call({display:1, sid:'hotILecturerHtm'}, lists);
}
CHRD.loadJs(mallJs + CHRD.obj2url({loads : 'hotILecturer', max:10, func : 'hotILecturer', listsLen:2}));//内训讲师
--loadjs返回的回调形式--
hotILecturer([{"lecturer":"张鼎昆","photo":"http://mall.chinahrd.net//UpLoads/Teachers/2011624121712997.jpg","job":"IT,金融","good":"人力资源","mobile":"13520881197","href":"ad69d671-497e-459b-898c-b368cf40f69a","hit":4248,"synopsis":"中国行动学习研究第一人","lists":[{"course":"基于“学习价值链”的整合式学习技术","price":"0.00","href":"http://mall.chinahrd.net/ProductInfo.aspx?id=8b85e084-fc2e-4cc5-a2ca-12c97d653c62","date":"","area":"","lecturer":"张鼎昆","hit":"10","category":"培训发展-行动学习","marketprice":"0.00","off":"非数字","mobile":"13520881197"},{"course":"行动学习工作坊――启动组织的双引擎战略","price":"0.00","href":"http://mall.chinahrd.net/ProductInfo.aspx?id=32f08614-bd0b-4c2b-9cf5-38f55c42eb31","date":"","area":"","lecturer":"张鼎昆","hit":"16","category":"培训发展,培训发展-行动学习","marketprice":"0.00","off":"非数字","mobile":"13520881197"}]},{"lecturer":"王新宇","photo":"http://mall.chinahrd.net//UpLoads/Teachers/20111228142310892.jpg","job":"通用","good":"招聘面试","mobile":"13520881197","href":"858d9191-1940-4272-adca-4ab1aa316b88","hit":3486,"synopsis":"原中外运集团人力资源部副总经理","lists":[{"course":"面试官实战训练-高效招募与选聘技巧","price":"1800.00","href":"http://mall.chinahrd.net/ProductInfo.aspx?id=cf219683-f00b-4050-b5b2-e9b68d0f18c4","date":"2012/2/24","area":"是","lecturer":"王新宇","hit":"1133","category":"人力资源,人力资源-招聘面试","marketprice":"3600.00","off":"0.5","mobile":""},{"course":"高效招募与选聘技巧","price":"0.00","href":"http://mall.chinahrd.net/ProductInfo.aspx?id=1eeeb396-41a1-495b-933e-352e086843bc","date":"","area":"","lecturer":"王新宇","hit":"25","category":"人力资源,人力资源-招聘面试","marketprice":"0.00","off":"非数字","mobile":"13520881197"}]}])
-----------------不足,对于搜索引擎不友好-----好处,分离模板制作与数据,不需要人工拼接html与数据----
标签:sub,--,标签,htm,js,html,var,模板
From: https://blog.51cto.com/u_252283/6181038