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');
});