Search code examples
javascriptdomselectors-api

What's the difference between queryAll and querySelectorAll


The definitions from the DOM Standard seems almost exactly the same, and I don't understand the difference.

What is the difference between queryAll and querySelectorAll.

The evaluation logic from DOM standard is below, but I am not smart enough to understand it.

query & queryAll

To match a relative selectors string relativeSelectors against a set, run these steps:

Let s be the result of parse a relative selector from relativeSelectors against set. [SELECTORS]

If s is failure, throw a JavaScript TypeError.

Return the result of evaluate a selector s using :scope elements set. [SELECTORS]

The query(relativeSelectors) method must return the first result of running match a relative selectors string relativeSelectors against a set consisting of context object, and null if the result is an empty list.

The queryAll(relativeSelectors) method must return an Elements array initialized with the result of running match a relative selectors string relativeSelectors against a set consisting of context object.

querySelector & querySelectorAll

To scope-match a selectors string selectors against a node, run these steps:

Let s be the result of parse a selector selectors. [SELECTORS]

If s is failure, throw a JavaScript TypeError.

Return the result of evaluate a selector s against node's root using scoping root node and scoping method scope-filtered. [SELECTORS].

The querySelector(selectors) method must return the first result of running scope-match a selectors string selectors against the context object, and null if the result is an empty list otherwise.

The querySelectorAll(selectors) method must return the static result of running scope-match a selectors string selectors against the context object.


Solution

  • query() and queryAll() accept a relative selector string, whereas querySelector() and querySelectorAll() do not. A relative selector is basically a selector which may be partial and start with a combinator:

    var parentNode = document.getElementById('parentNode'); // document.querySelector('#parentNode');
    
    // Find .childNode elements that are direct descendants (children) of parentNode
    // This cannot be done with querySelectorAll() using the existing reference to parentNode
    parentNode.queryAll('> .childNode');
    // querySelectorAll does allow getting all descendants of parentNode though
    parentNode.querySelectorAll('.childNode');
    

    But more importantly, queryAll() returns a live Elements[] array whereas the NodeList returned by querySelectorAll() is static, which means the nodes in that list are not updated when changes are made to their respective DOM elements.

    In terms of their functionality, query() and queryAll() may be more analogous to find() and findAll(), defined in Selectors API level 2 — where you'll also find the definition of a relative selector — as both method groups accept and work with relative selectors. Note that findAll() also returns a static NodeList, so they are still not completely identical.