DOM節點樹和元素樹--深度遍歷


我們在閱讀JS高級程序設計的時候,提到了節點樹的概念。比如說:

elem.parentNode---找elem的父節點

elem.childNodes---找elem的所有的直接子節點;

elem.nextSibling---找elem的下一個同輩節點‘;

elem.previousSibling---找elem的上一個同輩節點

因為childNodes包含看不見的空格文本,還有注釋等內容,所以使用起來不是太方便。

因此,JS又重新引入了元素樹的概念。這個的話,在我們實際應用中,用的比較普遍。

元素樹:僅僅包含元素節點的樹結構,不是一顆新樹,盡是節點數的子集;
elem.parentElement 找節點的父元素;
elem.children返回節點的所有子元素;
elem.firstElementChild 第一個直接子元素;
elem.lastElementChild 最后一個直接字元素;
elem.previousElementSibling 找elem的前一個兄弟元素;
elem.nextElementSibling 找elem的下個兄弟元素;

在這里,我們介紹一個筆試題:

遍歷一個指定父節點下的所有后代節點,這里需要明確一點,就是所有的后代節點都需要遍歷到:

復制代碼
1 <script type='text/javascript'>
 2          function getChildren(parent){
               //如果當前父節點不是文本節點,就輸出標簽名,否則輸出文本內容
 3              console.log(parent.nodeType!=3?parent.nodeName:parent.nodeValue);
               //獲得父節點的所有直接子節點
 4              var children = parent.childNodes;
               //遍歷children中每個節點
 5              for(var i =0,len =children.length;i<len;i++){
               //Step2: 對當前子節點調用getChildren
 6                  getChildren(children[i]);//這里使用遞歸的調用方法;
 7                  //console.log(children[i].nodeType !=3?children[i].nodeName:children[i].nodeValue);
 8              }
 9          }
10          getChildren(document.body);
11     </script>
復制代碼

這里我們需要知道一個算法-----深度優先遍歷:當同時有兄弟節點和子節點的時候,總是優先遍歷子節點。

上面代碼的遍歷順序,就是優先遍歷子節點。

我們在高性能JS這本書學到過,就是遞歸的運行效率沒有迭代的運行效率高,所以,我們優化的話,一般都需要把遞歸的循環優化成迭代的循環。

上面的例子如何修改呢,這里我們要提到一個新的概念,那就是:

 

NodeIterator 對象,可以對 DOM 樹進行深度優先的搜索

創建 NodeIterator 對象,需要使用 document 對象的 createNodeIterator() 方法,該方法接收四個參數:

  • root,搜索開始的節點
  • whatToShow,一個數值代碼,表示哪些節點需要搜索
  • filter,NodeFilter 對象,決定忽略哪些節點
  • entityReferenceExpansion,布爾值,表示是否需要擴展實體引用

whatToShow 參數:

  • NodeFilter.SHOW_ALL,顯示所有節點
  • NodeFilter.SHOW_ELEMENT,元素節點
  • NodeFilter.SHOW_ATTRIBUTE,屬性節點
  • NodeFilter.SHOW_TEXT,文本節點
  • NodeFilter.SHOW_CDATA_SECTION,![CDATA] 節點
  • NodeFilter.SHOW_ENTITY_REFERENCE,實體引用節點(&quot
  • NodeFilter.SHOW_ENTITY,實體元素節點(<!ENTITY foo "foo">
  • NodeFilter.SHOW_PROCESSING_INSTRUCTION,PI 節點
  • NodeFilter.SHOW_COMMENT,XML 注釋節點
  • NodeFilter.SHOW_DOCUMENT,文檔頂層節點
  • NodeFilter.SHOW_DOCUMENT_TYPE,DTD 節點
  • NodeFilter.SHOW_DOCUMENT_FRAGMNT
  • NodeFilter.SHOW_NOTATION
  • 我們重新修改后的代碼如下:
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    function getChildren(parent){
                      //獲取NodeIterator對象
                       var t = document.createNodeIterator(parent,NodeFilter.SHOW_ALL,null,false);
                       //循環遍歷對象的下一個節點;
                                  var currNode=null;
                       while((currNode=t.nextNode())!=null){
           
                           //節點不為空,就一直循環遍歷下去;直到為null,才中斷循環;
                         
                               console.log(node.nodeType!=3?node.nodeName:node.nodeValue)
                          
                       }
                  }
                        getChildren(document.body);


免責聲明!

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



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