遍历dom🌲

115 阅读1分钟

深度优先

深度优先, 使用递归

const root = document.getElementById("root");

function deepFirst(root: any, cb: (item: any) => void) {
  cb(root);

  getChildren(root).forEach((item) => deepFirst(item, cb));
}

function getChildren(item: any) {
  if (item.children) {
    return [...item.children];
  }
  return [];
}
// setTimeout 是为了等react渲染完成
setTimeout(() => {
  deepFirst(root, (item) => console.log(item));
}, 100);

也可以使用栈

  • 递归的本质就是栈,
  • 任何递归都可以用栈来实现
  • 栈: 先进后出
const root = document.getElementById("root");

function deepFirst(root: any, cb: (item: any) => void) {
  const arr = [root];

  while (arr.length) {
    const element = arr.pop();
    cb(element);
    getChildren(element)
      .reverse() // 入栈时要倒着入
      .forEach((item) => arr.push(item));
  }
}

function getChildren(item: any) {
  if (item.children) {
    return [...item.children];
  }
  return [];
}
// setTimeout 是为了等react渲染完成
setTimeout(() => {
  deepFirst(root, (item) => console.log(item));
}, 100);

过程

<h1>
    <h2 class='h2-1'>
      <h3 class='h3-1'></h3>
      <h3 class='h3-2'></h3>
      <h3 class='h3-3'></h3>
    </h2>
    <h2 class='h2-2'></h2>
</h1>

任何递归都可以用栈来实现

[h1]
// pop: h1; 
// push: h2-2,h2-1
[h2-2, h2-1]
// pop: h2-1
// push: h3-3, h3-2, h3-1, 记住要倒着push
[h2-2, h3-3, h3-2, h3-1] // h3-1出
[h2-2, h3-3, h3-2] // h3-2出
[h2-2, h3-3] // h3-3出
[h2-2] // h2-2出
[]

广度优先

广度优先用队列

  • 队列: 先进先出
const root = document.getElementById("root");

function breadthFirst(root: any, cb: (item: any) => void) {
  const arr = [root];

  while (arr.length) {
    const element = arr.shift(); // 先进先出
    cb(element);
    getChildren(element).forEach((item) => arr.push(item));
  }
}

function getChildren(item: any) {
  if (item.children) {
    return [...item.children];
  }
  return [];
}
// setTimeout 是为了等react渲染完成
setTimeout(() => {
  breadthFirst(root, (item) => console.log(item));
}, 100);

过程

<h1>
    <h2 class='h2-1'>
      <h3 class='h3-1'></h3>
      <h3 class='h3-2'></h3>
      <h3 class='h3-3'></h3>
    </h2>
    <h2 class='h2-2'></h2>
</h1>
// shift:  h1出
// push: h2-1进, h2-2进
[h1]
// shift: h2-1 出
// push: h3-1进,h3-2进,h3-3进
[h2-1, h2-2]
      [h2-2, h3-1, h3-2, h3-3]// h2-2出
            [h3-1, h3-2, h3-3]// h3-1出
                  [h3-2, h3-3]// h3-2出
                        [h3-3]// h3-3出
                            []