SearchinggetElement*, querySelector*
JavaScript Searching:getElement*, querySelector*
As you already know, JavaScript DOM is a tree-like structure, made of all the elements existing in your HTML document. (如您所知, JavaScript DOM是一个树状结构,由HTML文档中存在的所有元素组成。)
What is essential is that the HTML elements are floating around in a way that you want to access and read data from or change it. There exist many ways of finding those elements. (至关重要的是, HTML元素以您想要访问和读取数据或更改数据的方式浮动。有很多方法可以找到这些元素。)
In this chapter, you will find out what getElement* is used for, as well as the following two essential methods: querySelector and querySelectorAll.
Document.getElementById or Just ID
Document.getElementById or Just ID (Document.getElementById或Just ID)
The navigation properties of DOM are excellent when they are close to each other. Otherwise, additional searching methods are used. (当它们彼此靠近时, DOM的导航属性非常好。否则,将使用其他搜索方法。)
One of them is document.getElementById(id). You can use it when an element has the id attribute, no matter where it is. (其中一个是document.getElementById (id)。当元素具有id属性时,无论它在哪里,您都可以使用它。)
The example of using document.getElementById(id) is as follows:
let div = document.createElement('div');
div.id = 'content';
div.innerHTML = '<p>Create Element example</p>';
document.body.appendChild(div);
document.getElementById('content').style.padding = '10px';
document.getElementById('content').style.background = 'yellow';
document.getElementById('content').style.color = 'red';
You can also use a global variable, named by id, which references the element. The example will look like this:
let div = document.createElement('div');
div.id = 'content';
div.innerHTML = '<p>Create Element example</p>';
document.body.appendChild(div);
// content is a reference to DOM-element with id="content"
content.style.padding = '10px';
content.style.background = 'yellow';
content.style.color = 'red';
That works unless a JavaScript variable with the same name is declared. Then it takes precedence, like here:
let div = document.createElement('div');
div.id = 'elem';
document.body.appendChild(div);
let elem = 10; // now elem is 10, not a reference to <div id="elem">
console.log(elem); // 10
Please, note that id should be unique. There can be only a single element in the document with the given id. In case, different elements have the same id, the behavior of the methods that use it is unpredictable. It means that document.getElementById can return any of those elements at random. (请注意, ID应该是唯一的。文档中只能有一个具有给定ID的元素。如果不同的元素具有相同的id ,则使用它的方法的行为是不可预测的。这意味着document.getElementById可以随机返回任何这些元素。)
querySelectorAll
The most flexible method elem.querySelectorAll(css) returns all the elements inside elem matching the particular CSS selector. (最灵活的方法elem.querySelectorAll (css)返回elem中与特定CSS选择器匹配的所有元素。)
In the example below, the last children elements, are looked for:
let div = document.createElement('div');
div.id = 'elem';
document.body.appendChild(div);
let names = ['javascript', 'html', 'css', 'git'];
let ul = document.createElement('ul');
document.getElementById('elem').appendChild(ul);
names.forEach(function (name) {
let li = document.createElement('li');
ul.appendChild(li);
li.innerHTML += name;
});
let elements = document.querySelectorAll('ul > li:last-child');
for (let elem of elements) {
console.log(elem.innerHTML); // "git"
}
Definitely, it’s a powerful method, as you can use any CSS selector. Pseudo-classes in the CSS selector, such as :hover and :active are supported, as well. For example, document.querySelectorAll(’:hover’) can return the collection with elements that the pointer is over.
querySelector
The call to elem.querySelector(css) may return the initial element for the particular CSS selector. So, the result is equivalent to elem.querySelectorAll(css)[0], but the latter is searching for all the elements and picking one, while elem.querySelector, as a rule, looks for one. So, it’s much faster to write. (调用elem.querySelector (css)可能会返回特定CSS选择器的初始元素。因此,结果相当于elem.querySelectorAll (css) [0] ,但后者正在搜索所有元素并选择一个元素,而elem.querySelector通常会查找一个元素。因此,写作速度要快得多。)
Matches
Matches (匹配)
The methods above are used for searching the DOM. The elem.matches(css), doesn’t look for anything but checks whether el matches the particular CSS selector. It returns either true or false. (上述方法用于搜索DOM。elem.matches (css)不查找任何内容,只检查el是否与特定的CSS选择器匹配。它返回true或false。)
It comes handy when you iterate over elements trying to filter out the ones that interest you. (当你迭代元素试图过滤掉你感兴趣的元素时,它会派上用场。)
Let’s have a look at the example below:
<!DOCTYPE html>
<html>
<head>
<title>Title of the Document</title>
</head>
<body>
<a href="http://example.com/example.zip">Example</a>
<a href="http://w3cdoc.com">w3cdoc</a>
<script>
// can be any collection instead of document.body.children
(//可以是任何集合,而不是document.body.children)
for (let elem of document.body.children) {
if (elem.matches('a[href$="zip"]')) {
alert("The archive reference: " + elem.href );
}
}
</script>
</body>
</html>
Closest
Closest (最近)
An element’s ancestors are parent, the parent of the parent, its parent, and so on. Together the ancestors build the chain of parents from the element to top. The elem.closest(css) watches the closest ancestor that matches the CSS-selector. The elem is involved in the search, as well. That is to say, the method closest goes up from the element, checking each of the parents. When it matches the selector, the search finishes, and the ancestor is returned. (元素的祖先是父元素、父元素的父元素、父元素的父元素等。 祖先共同构建从元素到顶部的父母链。 Elem.closest (css) 监视与CSS选择器匹配的最近祖先。 Elem也参与了搜索。 也就是说,最接近元素的方法向上移动,检查每个父元素。 当它与选择器匹配时,搜索完成,并且返回祖先。)
The example of using the closest is the following:
let h1 = document.createElement('h1');
h1.innerHTML = 'Books';
document.body.appendChild(h1);
let div = document.createElement('div');
div.class = 'content';
div.id = 'elem'
document.body.appendChild(div);
let bookNames = ['javascript', 'html', 'css', 'git'];
let ul = document.createElement('ul');
ul.id = 'book'
document.getElementById('elem').appendChild(ul);
bookNames.forEach(function (name) {
let li = document.createElement('li');
ul.appendChild(li);
li.innerHTML += name;
li.id = 'chapter'
});
let chapter = document.querySelector('#chapter');
alert(chapter.closest('#book'));
alert(chapter.closest('#elem'));
alert(chapter.closest('h1')); // null, because h1 isn't an ancestor
getElementsBy*
getElementsBy* (getElementsBy *)
Let’s explore other methods, as well, that are mostly history, but can be found in old scripts. (让我们探索其他方法,这些方法大多是历史性的,但可以在旧脚本中找到。)
Among them are:
elem.getElementsByTagName(tag): it looks for element with a particular tag returning the collection of them. The tag parameters may also be “*”. elem.getElementsByClassName(className): it returns the elements with the given CSS class. document.getElementsByName(name): this one returns elements with particular name attribute, document-wide.
Live Collections
Live Collections (实时收藏)
Any “getElementsBy*” method returns a live collection. These collections reflect the current state of the document “auto-updating” it when it changes. (任何“getElementsBy *”方法都会返回实时集合。这些集合反映文档在更改时“自动更新”的当前状态。)
Below you can find to scripts:
let div1 = document.createElement('div');
document.body.appendChild(div1);
let divs = document.getElementsByTagName('div');
alert(divs.length); // 1
let div2 = document.createElement('div');
document.body.appendChild(div2);
alert(divs.length); // 2
The first script creates a reference to the <div> collection ( the length is 1). The second one runs after the browser sees one more <div> ( the length is 2).
On the contrary, querySelectorAll returns a static collection: like a fixed array of elements.
Using it instead will make the output of both scripts 1, like here:
let div1 = document.createElement('div');
document.body.appendChild(div1);
let divs = document.querySelectorAll('div');
alert(divs.length); // 1
let div2 = document.createElement('div');
document.body.appendChild(div2);
alert(divs.length); // 1
Now, the difference is noticeable. (现在,这种差异是显而易见的。)
Summary
Summary (概要)
Totally, there are six methods of searching for nodes in DOM. They are the following:
querySelector querySelectorAll getElementById getElementsByName getElementsByTagName getElementsByClassName (querySelector querySelectorAll getElementById getElementsByName getElementsByTagName getElementsByClassName)
The most used ones are the querySelector and querySelectorAll. However, getElementBy* comes in handy in the old scripts. (最常用的是querySelector和querySelectorAll。但是, getElementBy *在旧脚本中派上用场。)
The first two methods are extremely useful in complex documents. In this kind of documents, it is not so easy to target a specific element. (前两种方法在复杂文档中非常有用。在这种文档中,针对特定元素并不容易。)