如何计算 JavaScript 中嵌套元素的数量

Xav*_*ver 5 javascript

我有一个未知的、复杂的 DOM 结构,并搜索给定类 ( .bar) 的最大嵌套元素数。

我需要一个(递归)方法来返回嵌套元素的最大级别。在这个例子中它应该是3

<div class="root">
    <div class="foo"></div>
    <div class="foo">
        <div class="bar"> <!-- #1 -->
            <div class="foo"></div>
            <div class="foo"></div>
        </div>
    </div>
    <div class="foo"></div>
    <div class="foo">
        <div class="bar"> <!-- #1 -->
            <div class="foo"></div>
            <div class="foo"></div>
            <div class="foo">
                <div class="bar"> <!-- #2 -->
                    <div class="foo"></div>
                    <div class="foo"></div>
                    <div class="foo">
                        <div class="bar"> <!-- #3 --> <!-- << this is the "most nested element" -->
                            <div class="foo"></div>
                            <div class="foo"></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="foo"></div>
    <div class="foo">
        <div class="bar"> <!-- #1 -->
            <div class="foo"></div>
            <div class="foo"></div>
            <div class="foo"></div>
        </div>
    </div>
    <div class="bar"> <!-- #1 -->
        <div class="foo"></div>
        <div class="foo"></div>
        <div class="foo">
            <div class="bar"> <!-- #2 -->
                <div class="foo"></div>
                <div class="foo"></div>
                <div class="foo"></div>
            </div>
        </div>
    </div>
</div>

Run Code Online (Sandbox Code Playgroud)

所以我的方法是使用querySelectorAll( '.bar' )

let d = 0;

function my_counter(root, depth = 0) {
    //get all items
    let items = root.querySelectorAll('.bar');

    d = Math.max(d, depth);

    //for each item check
    items.forEach((item) => {
        my_counter(item, depth + 1);
    });

    return d;
}
Run Code Online (Sandbox Code Playgroud)

这种方法对我来说看起来很脏并且需要大量资源,所以我寻找更好的方法。此外,如果计数发生变化,因为元素可以被删除,Math.max则不尊重这一点。

Mr.*_*irl 2

这是一个递归函数,通过指定的选择器减少查询的子元素。

const findMaxDepth = (root, selector, depth = 0) =>
  [...root.querySelectorAll(selector)].reduce((maxDepth, child) =>
    Math.max(maxDepth, findMaxDepth(child, selector, depth + 1)), depth);

const root = document.querySelector('.root');

console.log("Max depth of '.bar':", findMaxDepth(root, '.bar')); // 3
console.log("Max depth of '.foo':", findMaxDepth(root, '.foo')); // 4
Run Code Online (Sandbox Code Playgroud)
<div class="root">
  <div class="foo"></div>
  <div class="foo">
    <div class="bar">
      <!-- #1 -->
      <div class="foo"></div>
      <div class="foo"></div>
    </div>
  </div>
  <div class="foo"></div>
  <div class="foo">
    <div class="bar">
      <!-- #1 -->
      <div class="foo"></div>
      <div class="foo"></div>
      <div class="foo">
        <div class="bar">
          <!-- #2 -->
          <div class="foo"></div>
          <div class="foo"></div>
          <div class="foo">
            <div class="bar">
              <!-- #3 -->
              <!-- << this is the "most nested element" -->
              <div class="foo"></div>
              <div class="foo"></div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div class="foo"></div>
  <div class="foo">
    <div class="bar">
      <!-- #1 -->
      <div class="foo"></div>
      <div class="foo"></div>
      <div class="foo"></div>
    </div>
  </div>
  <div class="bar">
    <!-- #1 -->
    <div class="foo"></div>
    <div class="foo"></div>
    <div class="foo">
      <div class="bar">
        <!-- #2 -->
        <div class="foo"></div>
        <div class="foo"></div>
        <div class="foo"></div>
      </div>
    </div>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)