js:模板解析实现2 -- 支持子列表

难度是对于子循环列表的解析,比第一个实现有更好的解析效果和应用

-----解析代码---



/*
 * 调用形式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="联系电话" />&nbsp;<!---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与数据----

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值