As you already know, JavaScript DOM is a tree-like structure, made of all the elements existing in your HTML document.
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.
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
The navigation properties of DOM are excellent when they are close to each other. Otherwise, additional searching methods are used.
One of them is document.getElementById(id). You can use it when an element has the id attribute, no matter where it is.
The example of using document.getElementById(id) is as follows:

You can also use a global variable, named by id, which references the element. The example will look like this:

That works unless a JavaScript variable with the same name is declared. Then it takes precedence, like here:

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.
querySelectorAll
The most flexible method elem.querySelectorAll(css) returns all the elements inside elem matching the particular CSS selector.
In the example below, the last children elements, are looked for:

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.
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.
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://w3docs.com">W3Docs</a>
<script>
// can be any collection instead of 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
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.
The example of using the closest is the following:

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
Any "getElementsBy*" method returns a live collection. These collections reflect the current state of the document “auto-updating” it when it changes.
Below you can find to scripts:

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:

Now, the difference is noticeable.
Summary
Totally, there are six methods of searching for nodes in DOM. They are the following:
- querySelector
- querySelectorAll
- getElementById
- getElementsByName
- getElementsByTagName
- getElementsByClassName
The most used ones are the querySelector and querySelectorAll. However, getElementBy* comes in handy in the old scripts.
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.