天天看點

JavaScript實作DOM樹的深度優先周遊和廣度優先周遊

// 深度周遊

function interator(node) {

    console.log(node);

    if (node.children.length) {

        for (var i = 0; i < node.children.length; i++) {

            interator(node.children[i]);

        }

    }

}

// 廣度周遊

function interator(node) {

    var arr = [];

    arr.push(node);

    while (arr.length > 0) {

        node = arr.shift();

        console.log(node);

        if (node.children.length) {

            for (var i = 0; i < node.children.length; i++) {

                arr.push(node.children[i]);

            }

        }

    }

}

————————————————

深度優先周遊

// 非遞歸,首次傳入的node值為DOM樹中的根元素點,即html

// 調用:deep(document.documentElement)

function deep (node) {

  var res = []; // 存儲通路過的節點

  if (node != null) {

    var nodeList = []; // 存儲需要被通路的節點

    nodeList.push(node);

    while (nodeList.length > 0) {

      var currentNode = nodeList.pop(); // 目前正在被通路的節點

      res.push(currentNode);

      var childrens = currentNode.children;

      for (var i = childrens.length - 1; i >= 0; i--) {

        nodeList.push(childrens[i]);

      }

    }

  }

  return res;

}

// 使用遞歸

var res = []; // 存儲已經通路過的節點

function deep (node) {

  if (node != null) { // 該節點存在

    res.push(node);

    // 使用childrens變量存儲node.children,提升性能,不使用node.children.length,進而不必在for循環周遊時每次都去擷取子元素

    for (var i = 0,  childrens = node.children; i < childrens.length; i++) {

      deep(childrens[i]);

    }

  }

  return res;

}

廣度優先周遊

// 遞歸

var res = [];

function wide (node) {

  if (res.indexOf(node) === -1) {

    res.push(node); // 存入根節點

  }

  var childrens = node.children;

  for (var i = 0; i < childrens.length; i++) {

    if (childrens[i] != null) {

      res.push(childrens[i]); // 存入目前節點的所有子元素

    }

  }

  for (var j = 0; j < childrens.length; j++) {

    wide(childrens[j]); // 對每個子元素遞歸

  }

  return res;

}

// 非遞歸

function wide (node) {

  var res = [];

  var nodeList = []; // 存儲需要被通路的節點

  nodeList.push(node);

  while (nodeList.length > 0) {

    var currentNode = nodeList.shift(0);

    res.push(currentNode);

    for (var i = 0, childrens = currentNode.children; i < childrens.length; i++) {

      nodeList.push(childrens[i]);

    }   

  }

  return res;

}

————————————————

版權聲明:本文為CSDN部落客「qinchao888」的原創文章,遵循 CC 4.0 BY-SA 版權協定,轉載請附上原文出處連結及本聲明。

原文連結:https://blog.csdn.net/GreyBearChao/article/details/82872441