【问题标题】:How to traverse the DOM to determine maximum nesting depth?如何遍历 DOM 以确定最大嵌套深度?
【发布时间】:2013-08-21 17:22:14
【问题描述】:

例如:

// ...
<body>
  <div>
    <div>
    </div>
  </div>
</body>
// ...

这个嵌套深度是 3?但更一般地说,我怎样才能遍历 DOM 来找到这些信息?

我有兴趣将 DOM 视为建模为对象字面量的 n 叉树,如本文所述:

n-ary tree in JavaScript

【问题讨论】:

  • 由于您不搜索特定内容或将任何算法应用于树的一部分,所以简单的按顺序 [完整] 树遍历有什么问题?
  • 很好,我将如何最好地实现它?
  • 递归是最简单的。试试吧!

标签: javascript html dom


【解决方案1】:

优雅的递归解决方案

使用此功能,如 - height(document.body)

function height(el) {
    if (!el.children)
        return 0;
    var max = -1;
    for ( var i = 0; i < el.children.length; i++) {
        var h = height(el.children[i]);
        if (h > max) {
            max = h;
        }
    }
    return max + 1;
}

【讨论】:

    【解决方案2】:
    function getMaximumDepth (element) {
        var child = element.firstChild;
        var childrenDepth = [];
    
        if ( ! child ) {
            return 1;
        }
    
        while (child) {
            childrenDepth.push( getMaximumDepth(child) );
            child = child.nextSibling;
        }
    
        return Math.max.apply(Math, childrenDepth) + 1;
    }
    

    演示:http://jsfiddle.net/53R2p/

    【讨论】:

      【解决方案3】:

      如果唯一的目标是确定最大嵌套级别,我会考虑使用querySelector(因为它应该得到很好的优化):

      function getMaxNestLevel() {
          var i = 1, sel = '* > *'; /* html > body is always present */
          while(document.querySelector(sel)) {
              sel += ' > *';
              i++;
          }
          return i;
      }
      

      Example(带有此 SO 页面标记的部分)

      【讨论】:

      • 我敢打赌,这比某种形式的 DOM 行走要慢得多。当然只有测试才能说明问题。
      • @CrazyTrain,你是对的,如果 DOM 变得非常大,嵌套级别超过 30 (jsfiddle.net/BBtYg/3),它会变得更慢(与 joellustigman 的解决方案相比)。但对于相对扁平的 DOM,嵌套级别约为 20,在 Firefox 和 IE11 中似乎要快一些 (jsfiddle.net/BBtYg/2)。
      • @Crazy - 我提名你写 jsperf!
      【解决方案4】:

      我个人最喜欢的是使用堆栈。您不断推送标签,直到到达相应/对称的结束标签。然后你可以弹出或做任何你想做的分析。这是来自 Comp Sci 数据结构类的经典示例。

      【讨论】:

      • 添加...继续推/弹出并保持您在变量中达到的最大堆栈大小。在最后一次流行之后,你就有了深度。为答案 +1。
      • 这是 DOM,而不是 HTML 标记。 “匹配标签”不需要堆栈。
      • 你是对的,Bergi。我正在从不同的角度看待它。
      • 确实如此,但是对于计算 n 叉树的高度,递归比迭代更简单。顺便说一句,为什么 n 元树向下生长,但有高度而不是深度?好奇的人想知道。
      • 你正在浏览 DOM。它已经被解析成一棵树。像大多数递归解决方案一样,有一个简单/特殊情况通常终止递归和一般情况。简单的情况是一棵不包含子树的树:它的高度是 1。一般(和递归的情况)是一棵包含 1 个或多个子树的树:它的高度是 1 + 其子树的最大深度(通过递归计算每个这样的子树并跟踪其最大值)。请参阅 @MoazzamKhan 的出色实施答案。
      猜你喜欢
      • 1970-01-01
      • 2018-04-14
      • 2015-11-17
      • 2016-07-29
      • 1970-01-01
      • 1970-01-01
      • 2021-02-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多