How to filter elements returned by QuerySelectorAll

I don't think I get the question right. Why would you want to "filter" the result of querySelectorAll() which infact, is some kind of a filter itself. If you query for div span or even better #id div, those results are already filtered, no ?

However, you can apply Array.prototype.filter to the static result of querySelectorAll like follows:

var filter   = Array.prototype.filter,
    result   = document.querySelectorAll('div'),
    filtered = filter.call( result, function( node ) {
        return !!node.querySelectorAll('span').length;
    });

That code would first use querySelectorAll() to query for all <div> nodes within the document. Afterwards it'll filter for <div> nodes which contain at least one <span>. That code doesn't make much sense and is just for demonstrative purposes (just in case some SO member wants to create a donk comment)

update

You can also filter with Element.compareDocumentPosition. I'll also tell if Elements are disconnected, following, preceding, or contained. See MDC .compareDocumentPosition()


Most concise way in 2019 is with spread syntax ... plus an array literal [...], which work great with iterable objects like the NodeList returned by querySelectorAll:

[...document.querySelectorAll(".myClass")].filter(el=>{/*your code here*/})


Note: NodeList is not a genuine array, that is to say it doesn't have the array methods like slice, some, map etc. To convert it into an array, try Array.from(nodeList).

ref: https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelectorAll

for example:

let highlightedItems = Array.from(userList.querySelectorAll(".highlighted"));

highlightedItems.filter((item) => {
 //...
})

Some browsers that support qsa also support a non-standard matchesSelector method, like:

element.webkitMatchesSelector('.someSelector')

...that will return a boolean representing whether element matched the selector provided. So you could iterate the collection, and apply that method, retaining positive results.

In browsers that don't have a matchesSelector, you'd probably need to build your own selector based method similar to the selector engine you're building.

Tags:

Javascript