ext源码阅读 - DomHelper - createHtml,insertHtml

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 + '"';
}

 

你可能感兴趣的:(create)