I have an unknown, complex DOM structure and searching for the max number of nested elements with a given class (.bar
).
I need a (recursive) method which returns the max levels of nested elements. In this example it should be 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>
So my approach would be to use 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;
}
This approach looks dirty and resource intensive to me so I look for a better. Also if the count change as elements can get removed Math.max
doesn’t respect that.
2
Answers
you can directly return and update the depth value in your recursive function. Additionally, since you’re only interested in the maximum depth of .bar elements, you don’t need to use querySelectorAll(‘.bar’) multiple times. Here’s a cleaner version of your code:
Here is a recursive function that reduces the queried child elements by a specified selector.