Reputation: 933
querySelectorALL() as specified by MDN donot support live nodes and return only static nodes.MDN querySelectorALL
Can querySelector() support live node MDN donot specified anything about itMDN querySelector
Upvotes: 5
Views: 5482
Reputation: 1073978
querySelectorAll
returns a static list (specifically, a static NodeList
), whereas (say) getElementsByTagName
returns a live list (specifically, a live HTMLCollection
).¹ It's the list that's static or live, not the nodes/elements on the list.
An element returned by querySelector
is the element in the DOM (as are the elements in the list from querySelectorAll
). They're "live," not snapshots or clones — e.g., if they're changed, you can see those changes via the reference you have from querySelector
/querySelectorAll
.
Example:
const element = document.querySelector("input");
const staticList = document.querySelectorAll("input");
const liveList = document.getElementsByTagName("input");
element.addEventListener("input", () => {
// Both of these are references to the live node in the DOM
console.log(element.value);
console.log(staticList[0].value);
});
document.getElementById("del").addEventListener("click", () => {
// Removing the input
document.body.removeChild(document.querySelector("input"));
// It's still on the static list
console.log("staticList.length = " + staticList.length); // 1
// It's off the live list now
console.log("liveList.length = " + liveList.length); // 0
// Since we still have a reference to it, we can still see it's value
console.log(element.value); // "what you typed"
});
Type something: <input type="text">
<br>then click this: <button id="del" type="button">Delete</button>
¹ HTMLCollection
instances are always live.² NodeList
instances may be either live or static (snapshots). The NodeList
you get from querySelectorAll
is static, but the NodeList
you get from (say) the childNodes
property of an Element
is live. Here's an example of that:
const container = document.getElementById("container");
console.log(`Get a static list of the container's elements`);
const list = container.querySelectorAll("*");
console.log(`It's a NodeList:`);
console.log(list.constructor.name); // "NodeList"
console.log(`With one element in it:`);
console.log(list.length); // 1
console.log(`Get a live list of children`);
const children = container.childNodes;
console.log(`It's also a NodeList:`);
console.log(children.constructor.name); // "NodeList"
console.log(`With one element in it (so far):`);
console.log(children.length); // 1
console.log(`Add a new child`);
const p = document.createElement("p");
container.appendChild(p);
console.log(`The static list still has one element:`);
console.log(list.length); // 1
console.log(`But the live list has two:`);
console.log(children.length); // 2
.as-console-wrapper {
max-height: 100% !important;
}
<div id="container"><p></p></div>
² "HTMLCollection
instances are always live." - Actually, the specification doesn't say that. I base that statement on two things:
HTMLCollection
instances the specification describes are live, and no new HTMLCollection
instances will be added in the future; it's a legacy type. If any new collections are added, they'll be defined either as Sequence<T>
instances or as NodeList
instances.Upvotes: 5