To make our web pages dynamic, we have to manipulate the elements on the page so that we can get the dynamic effects. The web browser’s standard library allows us to do this. There are multiple methods in the document
object, which is the object which represents the items on our page. It has the whole DOM tree with all the elements we can get and then manipulate. In this article, we’ll look at a few methods to get elements from the page.
getElementsByClassName
The document.getElementsByClassName
method lets us get a list of DOM objects on the page by their class name. Whatever object that has the given class will be returned by this method. It takes one argument which is a string with one or more class names separated by a space. It’s a method that’s part of any DOM element, which means it can also be called on elements that are returned by this method.
A NodeList
object is returned, which is an array-like object. It has a length
property and can be looped through by a for
loop or a for...of
loop, but array methods like forEach
aren’t included in this object.
The simplest example would be getting the elements from the following HTML:
<p class='foo'>
foo
</p>
<p class='foo'>
bar
</p>
Then in our JavaScript code, we can get the elements with the foo
class by writing the following:
const foo = document.getElementsByClassName('foo');
Once we have that we have access to the elements, so we can manipulate them by assigning values to its properties. For example, if we want to change the style, we can set the value of the properties in the style
property.
We can write something like the following to set the color of the text of both elements with the foo
class to red:
const foo = document.getElementsByClassName('foo');
for (const f of foo) {
setTimeout(() => {
f.style.color = 'red';
}, 2000)
}
Also, we can pass in more than one class name to the method. They have to be separated by a space. It’ll select the elements with all the classes. For example, if we add a bar
to the first p
element as follows:
<p class='foo bar'>
foo
</p>
<p class='foo'>
bar
</p>
Then we can write the following to change the first p
element’s text color to red after 2 seconds:
const foo = document.getElementsByClassName('foo bar');
for (const f of foo) {
setTimeout(() => {
f.style.color = 'red';
}, 2000)
}
The style
property has lots of properties. Pretty much any CSS option can be set by assigning a value to a property of the style
property.
getElementsByTagName
We can select all the elements with the given tag name by using the document.getElementsByTagName
method.
It accepts a string with the tag name and returns a NodeList object with all the elements with the given tag. As with any NodeList object, we can loop through by a for
loop or a for...of
loop, but array methods like forEach
aren’t included in this object.
For example, we can write the following code to set all the p
elements to red after 2 seconds given the following HTML code:
<p>
foo
</p>
<p>
foo
</p>
<div>
baz
</div>
We can write:
const pElements = document.getElementsByTagName('p');
for (const p of pElements) {
setTimeout(() => {
p.style.color = 'red';
}, 2000)
}
to set them to red since we passed in p
to the method. We should get that the first 2 elements are red after 2 seconds. We can see that the div
element stays black since it’s not a p
element.
getElementsByTagNameNS
The getElementsByTagNameNS
is very similar to the getElementsByTagName
method, but it takes 2 arguments instead of one. The first is a string with the XML namespace of the HTML document, and the second is the same as getElementsByTagName
‘s first argument, which is the tag name.
The namespace is the XML namespace, which is part of the syntax for defining a web page with XHTML instead of HTML.
The return value is the same as getElementsByTagName
, which is a NodedeList object with all the elements with the given tag and XML namespace.
For example, if we have the following HTML:
<html xmlns="[http://www.w3.org/1999/xhtml](http://www.w3.org/1999/xhtml)">
<head>
<title>Foo</title>
</head>
<body>
<p>
foo
</p>
<p>
foo
</p>
<div>
baz
</div>
<script src="main.js"></script>
</body>
</html>
Then we can write the following JavaScript code in main.js
to make the text of the p
elements red after 2 seconds:
const pElements = document.getElementsByTagNameNS('[http://www.w3.org/1999/xhtml'](http://www.w3.org/1999/xhtml%27), 'p');
for (const p of pElements) {
setTimeout(() => {
p.style.color = 'red';
}, 2000)
}
We have to name the HTML file with the .xhtml
extension to make it this method work since it’s only used for XHTML documents.
Photo by Will Smith on Unsplash
getElementById
The document.getElementById
method lets us get a DOM object on the page by ID. We can use it by passing in a string with the ID of the element that we want to select. Since there can only be one element with a given ID per page, it’ll only get one element and return that.
For example, if we have the following HTML:
<p id='foo'>
foo
</p>
Then we can set the color to red after 2 seconds by writing the following code:
const foo = document.getElementById('foo');
setTimeout(() => {
foo.style.color = 'red';
}, 2000)
querySelector
Selecting elements to manipulate are clumsy with the methods above since we can only select elements by ID or class name. With the querySelector
method, we can use any CSS selector to select an element.
It takes one argument which is a string with the CSS selector for the elements that we want to select. It returns an element object that is the first element that is selected by the CSS selector. It’ll throw a syntax error if the selector we pass in is invalid.
Special characters must be escaped with a backslash.
For example, if we have the following input:
<input type='text'>
Then we want to set a value to it by writing the following code:
const input = document.querySelector('input[type="text"]');
input.value = 'abc';
We can escape special characters in CSS selectors like in the following example. If we have an input with the ID abc
, which has the special character slash:
<input type='text' id="abc">
Then we can change its values like in the following code:
const input = document.querySelector('#abc');
input.value = 'abc';
Notice that we have 4 slashes to represent the slash character in the string.
If our element has a colon in the selector, like:
<input type='text' id="ab:c">
Then we can write:
const input = document.querySelector('#ab:c');
input.value = 'abc';
The colon is escaped by adding 2 slashes before it.
querySelectorAll
Like the querySelector
method, the querySelectorAll
takes a CSS selector string for the elements that we want to select. However, it returns a NodeList object with all the elements that match the CSS selector.
For example, if we can write the following HTML code:
<p class='foo'>
foo
</p>
<p class='foo'>
foo
</p>
<p class='baz'>
baz
</p>
Then we can select all the elements with the class .foo
and set the text to red after 2 seconds by writing the following code:
const fooElements = document.querySelectorAll('.foo');
for (const f of fooElements) {
setTimeout(() => {
f.style.color = 'red';
}, 2000)
}
Using the Methods Above with Non-Document Elements
We can use all these methods on non-document DOM objects. For example, if we have the following HTML code:
<div id='bar'>
<p class='foo'>
foo
</p>
<p class='foo'>
foo
</p>
<p class='baz'>
baz
</p>
</div>
Then we can select the bar
element with any method and, which returns the bar
element DOM object. Then we can use any method include the same one as we use before to select another element in the returned object.
For example, with the above HTML, we can write the following to select all the p
elements with the class foo
and set their text to red after 2 seconds:
const fooElements = document.querySelector('#bar').querySelectorAll('.foo');
for (const f of fooElements) {
setTimeout(() => {
f.style.color = 'red';
}, 2000)
}
If we replace querySelector
with some method that returns NodeList objects, then we’ve to loop through them with the for
or for...of
loop or get theme element by index.
Most of the methods above are very useful for getting DOM elements and manipulating them. However, we can probably ignore getElementByTagNameNS
since we don’t write XHTML files much anymore since HTML 5 was released.