ext源碼閱讀 – DomHelper – createHtml,insertHtml

來源:互聯網
上載者:User

createHtml參考:http://linder0209.iteye.com/blog/1071818

/**
 * 建立html
 * @param o
 * {tag:string,              // 元素的標記名,如果沒有,預設為div
     children|cn:string|Array|json, // 子結點對應的json數組或位元組點的html或單個json
     html:string,            // 對應的html,如果有cn或children屬性就忽略
     style:function|string|json,   // 元素的樣式,可以是函數,字串,json對象
     cls:string,            // 元素的class屬性的值
     htmlFor:string           // 元素的For屬性,
     x:y                  // x表示其他名字,y表示非函數、非空內容
   }
     var spec = {
         id: 'my-ul',
         tag: 'ul',
         cls: 'my-list',
         style : {width:'20px',height:'30px'},
         // append children after creating
         children: [     // may also specify 'cn' instead of 'children'
             {tag: 'li', id: 'item0', html: 'List Item 0'},
             {tag: 'li', id: 'item1', html: 'List Item 1'},
             {tag: 'li', id: 'item2', html: 'List Item 2'}
         ]
     };
 */
function createHtml(o){
    var b = '',
        cn,
        attr,
        val,
        key;
    if(typeof o == 'string'){ // 若是 string 類型,直接返回
        b = o;
    } else if(Ice.isArray(o)){ // 若是 array 類型, 如: [{ tag: 'li', id: 'item0' }]
        for(var i=0,len=o.length; i<len; i++){
            if(o[i]){
                b += createHtml(o[i]);
            }
        }
    } else { // 若是 object 類型
        b += '<' + (o.tag = o.tag || 'div'); // 若沒有 o.tag 屬性,則預設為 div, 如: <div
        for (attr in o) {
            val = o[attr];
            if(!confRe.test(attr)){ // 忽略 tag|children|cn|html,這四個是需自訂屬性
                if(typeof val == 'object'){ // 若是物件類型, 如: style : {width:'20px',height:'30px'}
                    b += ' ' + attr + '="'; // 如: style = "
                    for (key in val) {
                        b += key + ':' + val[key] + ';'; // 如: width=20px;height:30px
                    }
                    b += '"';
                } else { // 若不是物件類型, 如: id: 'my-ul'
                    b += ' ' + ({cls: 'class', htmlFor: 'for'}[attr] || attr) + '="' + val + '"'; // class,for對象處理
                }
            }
        }
        if(emptyTags.test(o.tag)){ // 根據xhtml規定,忽略單標籤,如: <hr />, <br />等
            b += '/>';
        } else {
            b += '>'; // 如: <div sytle="width=20px;height:30px">
            if(cn = o.children){
                b += createHtml(cn); // 如: <li id="item0">List Item 0</li><li id="item1">List Item 1</li>
            }
            b += '</' + o.tag + '>'; // 如: </div>
        }
    }
    return b; // 如: <ol style="width:20px;height:80px;"><li id="item0"></li></ol>

/**
 * 向DOM中插入一個HTML片段
 * @param where 插入的html與el的位置關係--- beforeBegin, afterBegin, beforeEnd, afterEnd.
 * @param el 內容元素
 * @param html HTML片段
 */
insertHtml: function(where, el, html){
    // innerHTML是唯讀:col、 colgroup、frameset、html、 head、style、table、tbody、 tfoot、 thead、title 與 tr
    // http://www.cnblogs.com/rubylouvre/archive/2009/12/14/1622631.html
    var hash = {},
        hashVal,
        rs,
        range,
        setStart,
        frag,
        rangeEl;
    where = where.toLowerCase();
    hash[beforebegin] = ['beforeBegin', 'previousSibling'];
    hash[afterend] = ['afterEnd', 'nextSibling'];
    // 為了使後面的代碼更易實現,這地方成兩部分實現,
    // 1. 在當前節點的外邊插入,就是if外邊
    // 2. 在當前節點的裡邊插入,在if裡邊做判斷
    if(el.insertAdjacentHTML){ // ie
        // 對ie的table進行單獨處理
        if(tableRe.test(el.tagName) && (rs = insertIntoTable(el.tagName.toLowerCase(), where, el, html))){
            return rs;
        }
        hash[afterbegin] = ['AfterBegin', 'firstChild'];
        hash[beforeend] = ['BeforeEnd', 'lastChild'];
        if((hashVal = hash[where])){
            el.insertAdjacentHTML(hashVal[0], html);
            return el[hashVal[1]];
        }
    } else { // 舊版 firefox, firefox 11 支援 insertAdjacentHTML
        range = el.ownerDocument.createRange();
        setStart = 'setStart' + (endRe.test(where) ? 'After' : 'Before');
        if(hash[where]){
            // setStartAfter() 把該範圍的開始點設定為緊鄰指定節點的節點之後
            // setStartBefore() 把該範圍的開始點設定為緊鄰指定節點之前
            range[setStart](el);
            // http://msdn.microsoft.com/zh-cn/library/hh673538(v=vs.85).aspx#createContextualFragment
            frag = range.createContextualFragment(html); // http://www.cnblogs.com/rubylouvre/archive/2011/04/15/2016800.html
            el.parentNode.insertBefore(frag, (beforebegin == where ? el : el.nextSibling));
            return el[(beforebegin == where ? 'previous' : 'next') + 'Sibling'];
        } else {
            rangeEl = (afterbegin == where ? 'first' : 'last') + 'Child';
            if(el.firstChild){
                range[setStart](el[rangeEl]);
                frag = range.createContextualFragment(html);
                if(afterbegin == where){
                    el.insertBefore(frag, el.firstChild);
                } else {
                    el.appendChild(frag);
                }
            } else {
                el.innerHTML = html;
            }
            return el[rangeEl];
        }
    }
    throw '非法插入點 -> "' + where + '"';
}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.