How to get all direct descendants that match a test condition with vanilla JS
Let’s say you have some HTML like this.
<div id="sandwiches">
<div id="one" class="tuna">This will match</div>
<div>
Hello, world!
<div id="two" class="tuna">This will not</div>
</div>
<div id="three" class="tuna">So will this</div>
</div>
You want to get only direct descendants of the #sandwich
element that have the .tuna
class: #one
and #three
. The #two
element also has the .tuna
class but is nested inside another element, so we don’t want that one.
You can use the Element.querySelectorAll()
method to get all elements by a certain selector inside another element, but it will search the entire tree in that element and return #one
, #two
, and #three
.
let sandwiches = document.querySelector('#sandwiches');
// Not what we want
let tuna = sandwiches.querySelectorAll('.tuna');
We could also try using the Node.children
property, but that returns all direct descendants, regardless of class.
// Not what we want, either
let tuna = sandwiches.children;
To do this, we need to combine Node.children
with a few other techniques.
We can use Array.from()
to turn the NodeList that Node.children
returns into an array, and then use the Array.filter()
method to remove an elements that don’t match a test we specify.
// This WILL work
let tuna = Array.from(sandwiches.children).filter(function (elem) {
return elem.matches('.tuna');
});