DOM树遍历之JS实现DFS&BFS

本文通过一个具体的HTML代码片段介绍了如何使用深度优先遍历(DFS)和广度优先遍历(BFS)来遍历DOM树。DFS总是先深入下一级节点,而BFS则是先遍历当前层级的所有节点。

我们一般可以采用DFS(深度优先遍历)BFS(广度优先遍历)来遍历DOM树

介绍 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遍历结果应为:

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

BFS则总是先遍历当前层级的所有节点,只有当当前层级所有节点都遍历结束后才会进入下一层级。对于上面例子BFS遍历结果应为:

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++
      }
    }
    
结果

先给大家补全代码:

// 输入节点信息
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);

上面例子的运行结果为:
运行结果

参考

破解前端面试(80% 应聘者不及格系列):从 DOM 说起
Javascript-ONLY DOM Tree Traversal - DFS and BFS?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值