JavaScript快速查找節點


 

我們在實際的開發中,經常要獲取頁面中某個html元素,動態更新元素的樣式、內容屬性等。

 

       

 


 

 我們已經知道在JavaScript中提供下面的方法獲取子、父、兄節點的方法:

  常規

通過節點獲取子節點:

  1. parentObj.firstChild                                            獲取已知父節點的第一個子節點 
  2. parentObj.lastChild                                            獲取已知父節點的最后一個子節點
  3. parentObj.childNodes                                             獲取已知父節點的子節點數組(這里我在IE 7中獲取的是所有直接的子節點)
  4. parentObj.children                                                  獲取已知節點的直接子節點數組(在IE7中和childNodes效果一樣)
  5. parentObj.getElementsByTagName(tagName)     返回已知子節點中類型為指定值的子節點數組

通過臨節點獲取兄弟節點:

  1. neighbourNode.previousSibing                              獲取已知節點的前一個兄弟節點
  2. neighbourNode.nextSibing                                      獲取已知節點的下一個兄弟節點

通過節點獲取父節點:

   1、childNode.parentNode                                             獲取已知節點的父節點

 

上面的方法基本都是可以遞歸是使用的,parentObj.firstChild.firstChild.firstChild...但是這樣的代碼有一種傻傻的趕腳。。

 


 

  擴展

在擴展之前,我們需要知道一些關於節點基礎的知識:Dom節點中,每個節點都擁有不同的類型

     W3C規范中常用的Dom節點的類型有以下幾種

節點類型 說明
元素節點 每一個HTML標簽都是一個元素節點 1
屬性節點 元素節點(HTML標簽)的屬性,如id,class,name等 2
文本節點 元素節點或屬性節點中的文本內容 3
注釋節點 便是文檔的注釋,形式如<!--comment Text--> 8
文檔節點 表示整個文檔(Dom樹的根節點,即document) 9

 

 

 

  關於節點的名稱,不同類型的節點對應不同的名稱

節點類型 節點名稱
元素節點 HTML的名稱(大寫)
屬性節點 屬性的名稱
文本節點 它的值永遠的都#text
文檔節點 它的值永遠都是#document

 

 

可以分別通過nodeType(節點類型)nodeName(節點名稱),以及nodeValue(節點值)分別返回節點的類型(比如元素節點返回1,屬性節點返回2)、節點名稱以及節點值;

 

JS獲取兄弟節點的兩種方法

  方法一:通過父元素的子元素先找到含自己在內的“兄弟元素”,然后在剔除自己

1 function sibling(elem){ 2    var a = []; 3    var b = elem.parentNode.children; 4    for (var i = 0 ; i < b.length ; i++){ 5       if(b[i] !== elem) a.push(b[i]); 6  } 7    return a; 8 }

 

  方法二:jQuery中實現方法,先通過查找元素的第一個子元素,然后在不斷往下找下一個緊鄰元素,判斷並剔除自己。

 1 siblings:function(elem)  2 {  3      return JQuery.sibling(elem.parentNode.firstNode,elem);  4 }  5 
 6 JQuery.sibling = function(n,elem){  7       var r = [];  8        for (;n;n= n.nextSibling){  9        if(n.nodeType == 1 && (!elem ||  elem  != elem)) 10  r.push(n); 11  } 12      return r; 13 }

 

在jQuery 1.2多的版本中都可以找到這段代碼,我看的jQuery1.2.3的版本,在1800行可以找到這段代碼:

 

把這個方法轉化為獨立可用的函數:

 1 fucntion sibling(elem){  2     var r = [];  3     var n = elem.parentNode.firstChild;  4     for(;n;n = n.nextSibling) {  5         if(n.nodeType === 1 && n !== elem) {  6  r.push(n);  7  }  8  }  9      return r; 10 }

        

很顯然通過這種方法查找特定節點的兄弟元素,可以很方便的避免的使用遞歸的冗余。

 

獲取所有元素節點

  在JavaScript中,可以通過children來獲取所有的子節點(只返回HTML中,甚至不返回子節點),幾乎得到了所有瀏覽器的支持,但是在Firefox有的版本中不支持。

  注意:在IE中,children包含注釋節點

  所以因為特殊情況的存在,有時候我們需要只獲取元素節點,這樣我們就可以通過nodeType屬性來進行篩選,用上面的知識:nodeType == 1的節點為元素節點。

下面,自定義一個函數來獲取所有的元素子節點:

 1 var getChildNodes = function(elem) {  2     var childArr = elem.children || elem.childNodes,  3           childArrTem = new Array();  4      for (var i = 0 ; i < childArr.length; i ++ ) {  5            if (childArr[i].nodeType == 1){  6  childArrTem.push(childArr[i]);  7  }  8  }  9    return childArrTem; 10 }

 

   獲取所有的節點

同樣的,我們可以獲取當前節點所有的父節點:

1 function getParents (elem){ 2   var parents = []; 3    while(elem.parentNode){ 4  parents.push(elem.parentNode) 5        elem = elem.parentNode; 6  } 7     return parents; 8 }

這樣我們可以接受一個dom節點,最終會獲取到document對象,如果只要獲取到最上層是body,可以把while里的判斷改為:  while(elem.parentNode && elem.parentNode.tagName == 'BODY' 

 

依據JavaScript中的提供的獲取節點的方法和相關的知識,我們可以寫出很多封裝的方法,嘗試一下,你可以寫出多少種獲取節點的方法呢?

當我們寫出了一些操作節點的封裝之后在去看jQuery中Dom操作節點方法的源碼會輕松很多呢。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM