DOM樹遍歷之JS實現DFS&BFS

咱們通常能夠採用DFS(深度優先遍歷)BFS(廣度優先遍歷)來遍歷DOM樹javascript

介紹 DFS & BFS

咱們來結合具體例子進行分析,給出HTML代碼片斷以下:前端

<div class="root">
  <div class="container">
    <section class="sidebar">
      <ul class="menu"></ul>
    </section>
    <section class="main">
      <article class="post"></article>
      <p class="copyright"></p>
    </section>
  </div>
</div>

DFS老是先進入下一級節點,只有當下一級沒有未遍歷的子節點時纔會進入到當前層級的其它節點。對於上面例子DFS遍歷結果應爲:java

root, container, sidebar, menu, main, post, copyright

BFS則老是先遍歷當前層級的全部節點,只有噹噹前層級全部節點都遍歷結束後纔會進入下一層級。對於上面例子BFS遍歷結果應爲:node

root, container, sidebar, main, menu, post, copyright

DFS的具體實現

DFS主要採用遞歸實現,依次遍歷節點,若是遍歷到的節點有子節點,則開始遍歷子節點面試

const DFSTraverse = (rootNodes, rootLayer) => {
      const roots = Array.from(rootNodes)
      while (roots.length) {
        const root = roots.shift()
        printInfo(root, rootLayer)
        // 若是有子節點,直接遍歷子節點,同時將層級加1
        if (root.children.length) {
          DFSTraverse(root.children, rootLayer + 1)
        }
      }
    }

BFS的具體實現

BFS採用隊列的思想,採用出隊的方式遍歷節點,若是遍歷到的節點有子節點,則將子節點入隊(這裏處理節點層級的方式比DFS更復雜一些,由於這裏將全部節點都放到了同一個數組中進行處理)數組

const BFSTraverse = (rootNodes, rootLayer) => {
      const roots = Array.from(rootNodes)
      const rootsLayer = [] // 單用一個數組存放每一個節點的的層級
      // 初始化
      for (let i = 0; i < roots.length; i++) {
        rootsLayer.push(rootLayer)
      }
      var rootIdx = 0 // 記錄當前處理roots中的第幾個節點,方便查找rootsLayer中對應的層級
      while (roots.length) {
        const root = roots.shift() // 出隊
        printInfo(root, rootsLayer[rootIdx])
        // 若是有子節點,將子節點放到roots隊列中
        if (root.children.length) {
          Array.prototype.push.apply(roots, Array.from(root.children))
          // 將當前層級加1獲得子節點的層級
          rootLayer = rootsLayer[rootIdx] + 1
          for (let i = 0; i < root.children.length; i++) {
            rootsLayer.push(rootLayer)
          }
        }
        // 處理下一個root節點
        rootIdx++
      }
    }

結果

先給你們補全代碼:app

// 輸入節點信息
const printInfo = (node, layer) => {
      var str = ''
      for (let i = 1; i < layer; i++) {
        str += ' '
      }
      console.log(`${layer}:${str}${node.tagName} .${node.className}`);
    }

console.log('DFS *******************************');
DFSTraverse(document.querySelectorAll('.root'), 1);
console.log('BFS *******************************');
BFSTraverse(document.querySelectorAll('.root'), 1);

上面例子的運行結果爲:
運行結果dom

參考

破解前端面試(80% 應聘者不及格系列):從 DOM 提及
Javascript-ONLY DOM Tree Traversal - DFS and BFS?ide

相關文章
相關標籤/搜索