五月综合缴情婷婷六月,色94色欧美sute亚洲线路二,日韩制服国产精品一区,色噜噜一区二区三区,香港三级午夜理伦三级三

您現(xiàn)在的位置: 365建站網(wǎng) > 365文章 > Jquery源碼分析之二:生成Dom元素

Jquery源碼分析之二:生成Dom元素

文章來源:365jz.com     點擊數(shù):383    更新時間:2009-09-14 10:31   參與評論

3、構(gòu)建JqueryDom元素

jQuery.fn.init函數(shù)中,最終的結(jié)果是把Dom元素放到jQuery對象的集合,我們可以傳入單個Dom元素或Dom元素集合直接把其存到jQuery對象的集合。但是如果第一個參數(shù)是string類型的話,如#id就要把Dom文檔樹去查找。對于html的片斷就得生成Dom元素。我們再進一步,傳入的單個Dom元素或Dom元素集合參數(shù)又是從那里來的?我們可以通過Dom元素的直接或間接的查找元素的方式。

這一部分首先分析如何從html的片斷就得生成Dom元素,然后分析jQuery是如何通過直接或間接的方式在在Dom樹中找到dom元素,第三就是分析基于CSS1~CSS3CSS selector。

 

3.1生成Dom元素

Init方法中通過jQuery.clean([match[1]], context);來實現(xiàn)把html片斷轉(zhuǎn)換成Dom元素,這是一個靜態(tài)方法:

// html轉(zhuǎn)換成Dom元素,elems多個html string 的數(shù)組

clean : function(elems, context) {

      var ret = [];

      context = context || document;//默認的上下文是document

      //IE!context.createElement行不通,因為它返回對象類型

      if (typeof context.createElement == 'undefined')

           //這里支持contextjQuery對象,取第一個元素。

       context = context.ownerDocument || context[0]

                     && context[0].ownerDocument || document;

 

    jQuery.each(elems, function(i, elem) {

// int 轉(zhuǎn)換成string的最高效的方法

       if (typeof elem == 'number')elem += '';

       if (!elem) return;// '',undefined,false等時返回

       if (typeof elem == "string") {// 轉(zhuǎn)換htmlDom元素

       // 修正 "XHTML"-style 標(biāo)簽,對于如<div/>的形式修改為<div></div>

        //但是對于(abbr|br|col|img|input|link|meta|param|hr|area|embed)

//不修改 。front=(<(\w+)[^>]*?)

elem = elem.replace(/(<(\w+)[^>]*?)\/>/g,                function(all, front, tag) {    return            tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)? all: front + "></" + tag+ ">";}   );

       // 去空格,否則indexof可能會出不能正常工作

       var tags = jQuery.trim(elem).toLowerCase(),

       div = context.createElement("div");//在上下文中創(chuàng)建了一個元素<div>

       // 有些標(biāo)簽必須是有一些約束的,比如<option>必須在<select></select>中間

       // 下面的代碼在大部分是對<table>中子元素進行修正。數(shù)組中第一個元素為深度          var wrap =

//<opt在開始的位置上(index=0)就返回&&后面的數(shù)組,這是對<option>的約束

!tags.indexOf("<opt")&& [1, "<select

multiple='multiple'>","</select>"]

    //<leg 必須在<fieldset>內(nèi)部

    || !tags.indexOf("<leg")&& [1, "<fieldset>", "</fieldset>"]

    //thead|tbody|tfoot|colg|cap必須在<table>內(nèi)部

    ||  tags.match(/^<(thead|tbody|tfoot|colg|cap)/)

&& [1, "<table>", "</table>"]

     //<tr<tbody>中間

    || !tags.indexOf("<tr")&& [2, "<table><tbody>", "</tbody></table>"]

     //tdtr中間

     (!tags.indexOf("<td") || !tags.indexOf("<th"))&& [3,

"<table><tbody><tr>","</tr></tbody></table>"]

     //col<colgroup>中間

    || !tags.indexOf("<col")&& [2,

"<table><tbody></tbody><colgroup>","</colgroup></table>"]

     //IE link script不能串行化 ?

    || jQuery.browser.msie&& [1, "div<div>", "</div>"]

     //默認不修正

    || [0, "", ""];

 

    // 包裹html之后,采用innerHTML轉(zhuǎn)換成Dom

    div.innerHTML = wrap[1] + elem + wrap[2];

 

    while (wrap[0]--)

    // 轉(zhuǎn)到正確的深度,對于[1, "<table>","</table>"],div=<table>

       div = div.lastChild;

 

    // fragments去掉IE<table>自動插入的<tbody>

    if (jQuery.browser.msie) {                          

   // 第一種情況:tags<table>開頭但沒有<tbody>。在IE中生成的元素中可能會自動

// 加的<tbody> 第二種情況:thead|tbody|tfoot|colg|captags,

// wrap[1] == "<table>" .tbody不一定是tbody,也有可能是thead等等

    var tbody = !tags.indexOf("<table")&& tags.indexOf("<tbody") < 0

               ? div.firstChild&& div.firstChild.childNodes

               : wrap[1] == "<table>"&& tags.indexOf("<tbody") < 0

                     ? div.childNodes: [];

    // 除去<tbody>

     for (var j = tbody.length - 1;j >= 0; --j)

         if (jQuery.nodeName(tbody[j],

 "tbody")&&!tbody[j].childNodes.length)                       tbody[j].parentNode.removeChild(tbody[j]);

 

    //使用innerHTML,IE會去開頭的空格節(jié)點的,加上去掉的空格節(jié)點

     if (/^\s/.test(elem))                              div.insertBefore(context.createTextNode

(elem.match(/^\s*/)[0]),div.firstChild);

    }

                    

    elem = jQuery.makeArray(div.childNodes);//elem從字符轉(zhuǎn)換成了數(shù)組

}

      //采用===0,因為form,select都有length屬性。這里主要是為了form,select

//行下面的if else 處理。對于其它的length === 0,也根本就不要加入到ret中。

if (elem.length === 0&& (!jQuery.nodeName(elem, "form")

                  && !jQuery.nodeName(elem, "select")))

                     return;

   //不是(類)數(shù)組的形式的元素,或是form元素或是select元素(這兩個可以看作類數(shù)組)

if (elem[0] == undefined|| jQuery.nodeName(elem, "form")|| elem.options)

       ret.push(elem);

else// 對于elemsarray-like的集合

    ret = jQuery.merge(ret, elem);

});

   //上面的each中把有效的元素都加入到ret,現(xiàn)在只要返回就得到轉(zhuǎn)換的Dom元素數(shù)組

return ret;

},

在上面的代碼中,我們可以看出對于elems, context的參數(shù)的支持是多種形式的,elems可以為(類)數(shù)組的形式,還可以采用對象的形式。數(shù)組中的元素或?qū)ο蟮膶傩钥梢允腔旌闲蔚?,?/span>string,ojbect,甚至(類)數(shù)組的形式。對于數(shù)字類型,會轉(zhuǎn)換在string形,除string形之外的都放入返回的數(shù)組中,當(dāng)然對于集合的形式,那就會取集合中每個元素。

對于string的形式就轉(zhuǎn)換成Dom元素的形式,之后存到返回的數(shù)組中。這是這個函數(shù)的主要任務(wù)。對于把html轉(zhuǎn)換成Dom元素,這里采用innerHTMLhtml掛到Dom文檔樹中。這樣就轉(zhuǎn)換成了Dom元素。

有些html標(biāo)簽片斷是有約束的,比如<td>xx</td>,它必須存在tabletr中,也就是說在要進行html的標(biāo)簽片斷的修正。這也是上面的代碼處理的重點。

文章來自:精靈部落

作者:prk(彭仁夔)   QQ546711211   email:sjkjs155@126.com   水平有限,難免有錯誤,請多多請教

 

 

Tag標(biāo)簽: Jquery

如對本文有疑問,請?zhí)峤坏浇涣髡搲?,廣大熱心網(wǎng)友會為你解答??! 點擊進入論壇

發(fā)表評論 (383人查看,0條評論)
請自覺遵守互聯(lián)網(wǎng)相關(guān)的政策法規(guī),嚴(yán)禁發(fā)布色情、暴力、反動的言論。
昵稱:
最新評論
------分隔線----------------------------

其它欄目

· 建站教程
· 365學(xué)習(xí)

業(yè)務(wù)咨詢

· 技術(shù)支持
· 服務(wù)時間:9:00-18:00
365建站網(wǎng)二維碼

Powered by 365建站網(wǎng) RSS地圖 HTML地圖

copyright © 2013-2024 版權(quán)所有 鄂ICP備17013400號