How to Manipulate the DOM Tree in JavaScript

In the last lesson, we introduced the concept of the DOM tree, and discussed how to select elements according to their ids, classes, names and element tags. And now, it is time to talk about how to manipulate the selected elements.

Altering the selected element

Let's start by talking about how to change a selected element.

Altering content

There are two properties available for altering the content of an element, innerHTML for all types of content, and textContent for textual content only.

  • innerHTML

The innerHTML property accesses the HTML content of an element. For example,

html
1<body>
2  <div id="parent">
3    <p id="first">Lorem ipsum dolor sit. . .</p>
4
5    <p id="second">
6      Quidem molestiae distinctio quae, <a href="">necessitatibus</a> deserunt
7      dignissimos. . .
8    </p>
9  </div>
10
11  <script src="index.js"></script>
12</body>
javascript
1let first = document.getElementById("first");
2console.log(first.innerHTML);
3
4let second = document.getElementById("second");
5console.log(second.innerHTML);

innerHTML

Notice that the result will be printed as a string. Even though #second has a child node (<a>), it is not treated as a node in this case.

You can use the innerHTML property to assign new content for the selected element.

javascript
1let first = document.getElementById("first");
2first.innerHTML = "This content is changed by JavaScript.";

change html content with innerHTML

The HTML content can be assigned as well.

javascript
1let second = document.getElementById("second");
2second.innerHTML =
3  "This content is changed by JavaScript. <a href=''>This link is changed by JavaScript as well.</a>";

change HTML content

However, this method of creating HTML nodes is generally not recommended, because it is likely that your code editor will not provide syntax highlighting, and it might lead to mistakes.

Later, we are going to introduce a more JavaScript way to create new HTML elements.

  • textContent

If you are only dealing with textual content, you can opt to use the textContent property instead.

javascript
1let first = document.getElementById("first");
2first.textContent = "This content is changed by JavaScript.";

Altering attribute

You are also allowed to programmatically change attributes using JavaScript. For example, let's say you have an image element:

html
1<img id="image" src="image.png" />

You can change the image source by setting the src attribute like this:

javascript
1let image = document.getElementById("image");
2
3image.src = "new_image.png";

You may also add new attributes to the selected element using the setAttribute() method.

javascript
1let image = document.getElementById("image");
2
3image.src = "new_image.png";
4image.setAttribute("alt", "This is an image.");

Altering style

There are generally two ways to change the styles of an element in frontend development. You can either change the styles directly, or change the class.

The styles of an element can be altered directly by specifying the style name. For example,

html
1<body>
2  <div id="parent">
3    <p id="first">Lorem ipsum dolor. . .</p>
4
5    <p id="second">. . .</p>
6
7    <p id="third">. . .</p>
8  </div>
9
10  <script src="index.js"></script>
11</body>
javascript
1let first = document.getElementById("first");
2
3first.style.color = "blue";

change style color

Changing the class attribute is also a commonly used technique, but the reason that we did not discuss it in the change attribute section is that it works differently compared to other attributes. Since class is a special keyword in JavaScript, and to avoid conflicts, you need to use either className or classList.

The className property is a setter, which means you can set the class by assigning a string directly.

html
1<body>
2  <div id="parent">
3    <p id="first" class="blue underline">Lorem ipsum dolor. . .</p>
4
5    <p id="second" class="blue bold">. . .</p>
6
7    <p id="third" class="red underline">. . .</p>
8  </div>
9
10  <script src="index.js"></script>
11</body>
css
1.blue {
2  color: blue;
3}
4
5.red {
6  color: red;
7}
8
9.underline {
10  text-decoration: underline;
11}
12
13.bold {
14  font-weight: 700;
15}
javascript
1let first = document.getElementById("first");
2
3first.className = "red underline bold";

change class

On the other hand, classList is read-only. You cannot edit it directly and must use the add() or remove() methods instead.

javascript
1let first = document.getElementById("first");
2
3first.classList.remove("blue");
4first.classList.add("red");
5first.classList.add("bold");

Adding new elements

Adding new elements to the DOM tree is slightly more complicated, as it usually takes four steps:

  • Create an element node.
  • Create a text node if the element needs one.
  • Attach the text node as the child of the element.
  • Insert the element node into the DOM tree.

In this section, we'll explain each of these steps one by one. Assuming this is your HTML document:

html
1<body>
2  <div id="parent">
3    <p id="first" class="blue underline">Lorem ipsum dolor. . .</p>
4
5    <p id="second" class="blue bold">. . .</p>
6
7    <p id="third" class="red underline">. . .</p>
8  </div>
9
10  <script src="index.js"></script>
11</body>

Creating element and text nodes

First of all, to create a new element node, you need to use the createElement() method.

javascript
1let p = document.createElement("p");

Next, to create and attach a text node, you can either use a createTextNode() method:

javascript
1let text = document.createTextNode(
2  "This paragraph is created with JavaScript."
3);

And then append the text node to the paragraph node we just created.

javascript
1p.appendChild(text);

Or simply use the innerHTML or textContent properties we discussed before.

javascript
1p.innerHTML = "This paragraph is created with JavaScript.";
javascript
1p.textContent = "This paragraph is created with JavaScript.";

Inserting nodes to DOM tree

Lastly, to insert the new paragraph into the DOM tree, you have a few options.

  • append() and appendChild(): append as child

The append() and appendChild() methods both insert a new node after the last child of the selected element. For example,

html
1<div id="parent">
2  <p id="first" class="blue underline">Lorem ipsum dolor. . .</p>
3
4  <p id="second" class="blue bold">. . .</p>
5
6  <p id="third" class="red underline">. . .</p>
7</div>
javascript
1let parent = document.getElementById("parent");
2// parent.append(p);
3parent.appendChild(p);

Both append() and appendChild() should give the same result:

html
1<div id="parent">
2  <p id="first" class="blue underline">Lorem ipsum dolor. . .</p>
3
4  <p id="second" class="blue bold">. . .</p>
5
6  <p id="third" class="red underline">. . .</p>
7  <p>This paragraph is created with JavaScript.</p>
8</div>

Their difference is that append() allows you to append multiple nodes, whereas appendChild() can only append one.

javascript
1let parent = document.getElementById("parent");
2parent.append(p1, p2);
  • prepend(): prepend as child

The prepend() method inserts a new node before the first child of the selected element. For instance,

javascript
1let parent = document.getElementById("parent");
2parent.prepend(p);
html
1<div id="parent">
2  <p>This paragraph is created with JavaScript.</p>
3  <p id="first" class="blue underline">Lorem ipsum dolor. . .</p>
4
5  <p id="second" class="blue bold">. . .</p>
6
7  <p id="third" class="red underline">. . .</p>
8</div>

There isn't a prependChild() method available.

  • before() and insertBefore(): insert before as sibling

The before() method inserts one or more nodes before the selected element.

javascript
1let parent = document.getElementById("parent");
2parent.before(p);
html
1<p>This paragraph is created with JavaScript.</p>
2<div id="parent">
3  <p id="first" class="blue underline">Lorem ipsum dolor. . .</p>
4
5  <p id="second" class="blue bold">. . .</p>
6
7  <p id="third" class="red underline">. . .</p>
8</div>

The insertBefore() method inserts the new node before the reference node, under the selected parent node. For example,

javascript
1let parent = document.getElementById("parent");
2parent.insertBefore(p, parent.children[1]);

In this case, parent is selected as the parent node. The second child element of parent (parent.children[1]) is used as the reference node. The new element p will be inserted before that reference node.

html
1<div id="parent">
2  <p id="first" class="blue underline">Lorem ipsum dolor. . .</p>
3
4  <p>This paragraph is created with JavaScript.</p>
5  <p id="second" class="blue bold">. . .</p>
6
7  <p id="third" class="red underline">. . .</p>
8</div>

There aren't any methods available for you to insert a node after as a sibling, because this action may be emulated by combining the insertBefore() method with nextSibling. For instance,

javascript
1parent.insertBefore(p, parent.children[1].nextSibling);
html
1<div id="parent">
2  <p id="first" class="blue underline">Lorem ipsum dolor. . .</p>
3
4  <p id="second" class="blue bold">. . .</p>
5  <p>This paragraph is created with JavaScript.</p>
6
7  <p id="third" class="red underline">. . .</p>
8</div>
  • replaceChild() and replaceWith(): replace an element

Lastly, you can replace existing elements with a new element. The replaceChild() method takes two arguments, the new child and the old child. It will replace the old one with the new one. For example,

javascript
1let parent = document.getElementById("parent");
2let second = document.getElementById("second");
3
4parent.replaceChild(p, second);
html
1<div id="parent">
2  <p id="first" class="blue underline">. . .</p>
3
4  <p>This paragraph is created with JavaScript.</p>
5
6  <p id="third" class="red underline">. . .</p>
7</div>

The replaceWith() method replaces the selected node with the new element.

javascript
1let second = document.getElementById("second");
2
3second.replaceWith(p);

Removing elements

To remove an element, use the remove() method.

javascript
1let second = document.getElementById("second");
2
3second.remove();

To remove the child of a selected element, use removeChild().

javascript
1let parent = document.getElementById("parent");
2
3parent.removeChild(parent.children[1]);