Selectors are a very powerful feature of Css. In the past, they were usually used to get page elements through getElementById and getElementsByTagName, which was inconvenient in some scenarios.

DOM later extended the Selector API standard, which contains the Selector API Level 1 querySelector and querySelectorAll methods, which can match page elements through Css selectors.

QuerySelector queries individual elements

QuerySelector is used to query for the first Element in a page that matches the rule. It can be called on both the Document and Element instances, taking a selector string argument and returning an HTMLElement object if found, or null otherwise.

The syntax is as follows:

Document instance querySelector; Element instance. QuerySelector;Copy the code

1. Document instance call

The Document instance call gets the matching element for the entire page.

A simple example is as follows:

// Get the body element
let body = document.querySelector("body");
console.log(body)

// Get the element whose ID is container. Only the first one will be retrieved
let container = document.querySelector("#container");
console.log(container)

// Get the element in class that contains BTN, only the first one will be fetched
let btn = document.querySelector(".btn");
console.log(btn);

// Get the element containing BTN from the direct subclass of Container
let containerBtn = document.querySelector("#container>.btn");
console.log(containerBtn);
Copy the code

2. Element instance call

The Element instance call gets the matched elements in the Element’s subtree.

A simple example:

// Get the element whose ID is Container
let container = document.querySelector("#container");
// We need to check whether the element object exists, so that there is a querySelector method
if (container) {
	// Only look for elements in the container whose class contains BTN.
	let containerBtn = container.querySelector(".btn");
	console.log(containerBtn);
}
Copy the code

Theoretically, because Css can fetch any Element on a page through a selector, the Element instance call can be written as a Document instance call, simply by modifying the selector string argument.

For example, the above example can be written as follows:

let containerBtn = document.querySelector("#container .btn");
Copy the code

And because there is one less if judgment, the code is much cleaner. Of course, in some business scenarios where an ELement instance is already identified, it is more convenient to call it directly from the ELement instance.

QuerySelectorAll Queries all elements

The querySelectorAll method is similar to the querySelector method, except that it returns all matched elements of type NodeList.

A simple example:

// Suppose the page has two div class names that contain article

// Get all elements of the class that contain article
let articleList = document.querySelectorAll(".article");
console.log(articleList);
console.log(articleList.length);
// Console output:
//	NodeList(2) [div.article, div.article]
/ / 2
Copy the code

The querySelectorAll method returns all elements, which are often traversed in practice using the regular for, for of, and forEach traversals.

// for a loop
for (let item of articleList) {
	console.log(item);
}
/ / for traversal
for (let i = 0; i < articleList.length; i++) {
	console.log(articleList[i]);
	console.log(articleList.item(i));
}
/ / forEach traversal
articleList.forEach((item, index) = > {
	console.log(item, index);
});
Copy the code

For in traversal problem

If you iterate for in, you will iterate through some of the methods on the prototype chain, such as entries, forEach, etc.

Snapshots rather than real-time issues

The NodeList obtained using the querySelectorAll method is a snapshot, not real-time data.

Consider the following example:

// Use querySelectorAll, articleList is static, not real-time
let articleList = document.querySelectorAll(".article");
console.log(articleList);
console.log(articleList.length); / / 2

setTimeout(() = > {
	// Add an element
	let div = document.createElement("div");
	div.className = "article";
	document.body.appendChild(div);
	
	console.log(articleList);
	// Same as 2
	console.log(articleList.length);
}, 0);
Copy the code

Finally, I set a timer to fill the page with an Article div element with an articleList of length 2.

If you get it with getElementsByClassName, then articleList is real-time data. Here’s an example:

// Use getElementsByClassName, articleList is real-time
let articleList = document.getElementsByClassName("article");
console.log(articleList);
console.log(articleList.length);

setTimeout(() = > {
	// Add an element
	let div = document.createElement("div");
	div.className = "article";
	document.body.appendChild(div);
	
	console.log(articleList);
	// This is 3
	console.log(articleList.length);
}, 0);
Copy the code

View the print on the console:

The object you get with getElementsByClassName is an HTMLCollection type that changes with the document flow.

summary

  1. QuerySelector and querySelectorAll get page elements from Css selectors and are very powerful.
  2. QuerySelectorAll fetches elements as snapshots, static, not real-time.