Query Selector AllLoading saved progress…

Query Selector All

document.querySelectorAll('nav ul li a') feels like magic, but underneath it's two ideas stacked: match a single element against a compound selector (a tag/class/id/attribute run with no spaces), and honor the descendant combinator — the space that says "…somewhere inside a…". This exercise builds the second half on top of the first: given a selector made of several compounds separated by whitespace, find every element under a root whose ancestor chain satisfies the earlier compounds.

Implement querySelectorAll(root, selector). Return matching elements in document order, each once. See MDN: querySelectorAll.

Signature

function querySelectorAll(root, selector) {
  // returns an array of matching descendant elements, in document order
}

Examples

// <ul><li><a>x</a></li><li><div><a>y</a></div></li></ul>
querySelectorAll(root, 'ul a'); // [<a>x</a>, <a>y</a>] — a at any depth under ul
// <div class="menu"><ul><li><a>hit</a></li></ul></div><a>miss</a>
querySelectorAll(root, '.menu ul a'); // [<a>hit</a>] — full chain required

Notes

  • The space means "descendant", not "child"ul a matches an <a> any number of levels below a <ul>, not only a direct child.
  • Document order, deduplicated — return elements in the order they appear in the tree; an element with two matching ancestors still appears once.
  • Compounds are the unit — split on whitespace; within a compound (a.btn[href="/x"]) all parts must hold on the same element. Reuse the compound-matching idea from css-selector-matches.
  • Only the descendant combinator — no need to handle >, +, ~, or comma-separated selector lists here.
Loading editor…