Understanding DOM Manipulation with JavaScript
Published: 2024-04-17 10:02:28

Document Object Model or DOM is a programming interface that allows JavaScript to manipulate elements in an HTML document.   
  
When an HTML code is loaded in a browser, the browser parses it. In order to make these web pages and HTML documents dynamic, the browser lets JavaScript tap into the power of the DOM to access nodes and elements within the HTML file in a hierarchical form.

DOM can easily be seen as an Application Programming Interface (API) for accessing and manipulating HTML files. 

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1688593774719/467c9974-f97f-4196-a31b-ecc93aed3249.png align="center")

In this article, we will look at how to use the document object to select elements, traverse the DOM, insert, remove, and replace elements

## **Selecting Elements in the DOM**

You can select elements within the Document Object Model (DOM) using various methods available through the document object. These methods allow you to select either a single element or multiple elements. These methods are:

### **getElementById()**

`document.getElementById()` access elements with a specific id that matches the one mentioned in the string. 

```xml
<html>
 		 <head>
    			<title>DOM Manipulation</title>
   			<script src="./app.js" defer></script>
  		</head>
  		<body>
    		    <h1 id="heading"> JavaScript getElementById() 
              </h1>
		    <ul class="parent">
        		   <li class="item">First Item</li>
        		   <li class="item">Second Item</li>
      	    </ul>
  		</body>
</html>
```

```javascript
const element = document.getElementById("heading");
```

The id is unique within an HTML document. However, HTML is a forgiving language. If the HTML document has multiple elements with the same id, the `document.getElementById()` method returns the first element it encounters. In cases where the ID given does not exist, it returns null.

### **getElementByClassName()**

`document.getElementByClassName()` is used to access elements with specific class names. These names would be passed as arguments to the method when it is called. 

It returns an array-like (not everything you can do on an array works there) object of the child elements with a specified class name. 

These arrays are called HTML collections and are different from true Javascript arrays. Therefore,  not all array operations can work with these HTML collections.

Just like `document.getElementById()`, `document.getElementByClassName()` method returns the first element it encounters. In cases where the class name given does not exist, it returns null.

Here is a code snippet that describes how `getElementsByClassName()` works with HTML elements:

```xml
<html>
  		<head>
   			<title>DOM Manipulation</title>
    			<script src="./app.js" defer></script>
  		</head>
  		<body>
    			<nav>
     		   <ul class="parent">
        			<li class="item">First Item</li>
        			<li class="item">Second Item</li>
      		   </ul>
    			</nav>
  		</body>
</html>
```

```javascript
const items = document.getElementsByClassName("item");
```

In the code snippet, the first element with the class `item` is selected and stored in a variable `items`.

### **querySelector()**

`document.querySelector()` is a method that allows you to select the first element that matches the CSS selector.

```xml
<html>
  		<head>
    			<title>DOM Manipulation</title>
    			<script src="./app.js" defer></script>
  		</head>
  		<body>
    		   <nav>
      		 <ul>
        		    <li class="item">First Item</li>
                  <li class="item">Second Item</li>
                  <li class="item">Third Item</li>
      		 </ul>
    		   </nav>
  		</body>
</html>
```

```javascript
const items = document.querySelector("li");
console.log(items);
```

In this code, the js script uses the `document.querySelector("li")`  to select the first li element.

## **Selecting Multiple Elements in the DOM**

When it comes to selecting multiple elements within the DOM, there are several methods you can use. These methods typically return a collection of elements that matches specific criteria. Here are some commonly used approaches:

### **querySelectorAll()**

`document.querySelectorAll()` is used to select all elements with a CSS selector. It returns a static `NodeList` of elements. This means that it does not change or reflect when tag names are deleted to added.

```xml
<html>
  		<head>
    			<title>DOM Manipulation</title>
    			<script src="./app.js" defer></script>
  		</head>
  		<body>
    		   <nav>
      		 <ul>
        		    <li class="item">First Item</li>
                  <li class="item">Second Item</li>
                  <li class="item">Third Item</li>
      		 </ul>
    		   </nav>
  		</body>
</html>
```

```javascript
const items = document.querySelectorAll("li");
console.log(items);
```

From the above JavaScript code, we can easily select all the elements with the `li` CSS selector. 

**P S:** This should not be confused with `querySelector()`. `querySelector()` selects just the first element with a specific CSS selector. While `querySelectorAll()` selects all elements with a specific CSS selector

### **getElementByTagName()**

`document.getElementByTagName()` allows the selection of all elements that match a tag name. It returns a live HTMLCollection of elements. This means that it automatically reflects changes when tag names are deleted to added. For example,

```xml
<html>
  		<head>
    			<title>DOM Manipulation</title>
    			<script src="./app.js" defer></script>
  		</head>
  		<body>
    			<h1>Tag Name 1</h1>
    			<p>This is for some random text</p>
   			<h1>Tag Name 2</h1>
    			<p>This is for some more random text</p>
    			<h1>Tag Name 3</h1>
    			<p>This is for some other random text</p>
  		</body>
</html>
```

```javascript
const headings = document.getElementsByTagName("h1");
console.log(headings);
```

In the JavaScript code snippet, all of the elements with the tag name `h1` are selected and displayed.

## **Traversing the DOM**

DOM Traversing is the process of moving or selecting an element from another element. 

It involves navigating the Document Object Model(DOM) tree to access and manipulate elements. 

Traversing can occur in three directions: 

* Upwards
    
* Sideways
    
* Downwards
    

### **Upward traversing** 

This involves accessing a child element from its parent element or ancestors. The most common method used for upward traversing is `parentElement()`.

#### **Using parentElemet or parentNode**

You can traverse up the DOM using `parentElement()` or `parentNode()`. This lets you access the element/node that encloses the current element.

```xml
<html>
  		<head>
    			<title>DOM Manipulation</title>
    			<script src="./app.js" defer></script>
  		</head>
         <body>
     	   <ul class="parent">
        		<li class="child">First Item</li>
       		<li class="child">Second Item</li>
        		<li class="child">Third Item</li>
      	   </ul>
 		</body>
</html>
```

```javascript
const item = document.querySelector(".child");
const parentN = item.parentNode
const parentEl = item.parentElement
console.log(parentN);
console.log(parentEl)
```

In the JavaScript code snippet,  the first element with the class `child` is selected and stored in a variable `item`. Now, we can use the parentNode and parentElement methods to access this element's parent node and parent element. 

### **Sideways traversing**

This involves moving between elements that share the same parent. These elements are also referred to as sibling elements. The most common methods used for sideways traversing are  nextElementSibling and previousElementSibling

#### **Using nextElementSibling and previousElementSibling**

When navigating the DOM sideways we can select the next element using `nextElementSibling` and select the previous element using `previousElementSibling`.

```xml
<html>
  		<head>
    			<title>DOM Manipulation</title>
    			<script src="./app.js" defer></script>
  		</head>
  		<body>
     	   <ul class="parent">
        		<li class="child">First Item</li>
       		<li class="child">Second Item</li>
        		<li class="child">Third Item</li>
      	   </ul>
 		</body>
</html>
```

```javascript
const firstItem = document.querySelector("li");
console.log(firstItem.nextElementSibling);
const secondItem = document.querySelectorAll("li")[1];
console.log(secondItem.previousElementSibling);
```

This might be a bit confusing so let’s break down the code:

**Line 1** we select the first element with the tag name `li` and store it in a variable named `firstItem`.

**Line 2** we easily access the next element of the `firstItem` using the `nextElementSibling` method. 

**In line 3** we use querySelectorAll() to access all elements with the tag `li`, then we use the index \[1\] to select just the second element with the tag `li`, storing it in a variable named `secondItem`”

**Line 4** we easily access the previous element of secondItem using the `previousElementSibling()` method.

**<mark>PS</mark>**<mark>:</mark> This should give further clarity on the differences between `querySelector()` and `querySelectorAll()` and how they are used.

### **Downward Traversing**

This involves moving from a parent element to its child elements. In navigating the DOM downwards, we can use the children property to select direct descendants of the current element.

#### **Selecting children Element**

In navigating the DOM downwards, we can use the children property to select direct descendants of the current element.

```xml
<html>
  		<head>
    			<title>DOM Manipulation</title>
    			<script src="./app.js" defer></script>
  		</head>
  		<body>
     	   <ul class="parent">
        		<li class="child">First Item</li>
       		<li class="child">Second Item</li>
        		<li class="child">Third Item</li>
      	   </ul>
 		</body>
</html>
```

```javascript
const parent = document.querySelector(".parent");
const children = parent.children;
```

In the JavaScript code snippet, the first element with the class `parent` is selected and stored in a variable `parent`. Now, we can use the children method to access the descendants of the element.

## **Creating HTML Elements in JavaScript**

We can create new HTML elements from a Javascript code using the `document.createElement()` method.  This method takes an argument of the type of element we want to create. 

For example:

```xml
<html>
  		<head>
    			<title>DOM Manipulation</title>
    			<script src="./app.js" defer></script>
  		</head>
  		<body>
     	   <ul class="parent">
        		<li class="child">First Item</li>
       		<li class="child">Second Item</li>
        		<li class="child">Third Item</li>
      	   </ul>
 		</body>
</html>
```

We can use the `createElement()` method to create a new `<li>` element in JavaScript code.

```javascript
const newList = document.createElement("li");
```

Now, we can easily add some content to the `newList` using the `textContent` method;

```javascript
const newList = document.createElement("li");
newList.textContent = "Fourth Item";
console.log(newList)
```

The output would be "Fourth Item".

Quite interesting, isn't it? With this, we can easily add elements and text content into existing HTML code in just a few lines of code. We can now go ahead to insert this into the existing list in the HTML code as a fourth Item.

## Inserting Elements

We have seen how we can select and create elements, now we can easily insert elements in the DOM.  

We can easily do this using the `append()` or `appendChild()` method. For example, we would use one of these to insert a new list as the Fourth Item in the HTML code.

```xml
<html>
  		<head>
    			<title>DOM Manipulation</title>
    			<script src="./app.js" defer></script>
  		</head>
  		<body>
     	   <ul class="parent">
        		<li class="child">First Item</li>
       		<li class="child">Second Item</li>
        		<li class="child">Third Item</li>
      	   </ul>
 		</body>
</html>
```

```javascript
const items = document.querySelector("ul")
const newList = document.createElement("li");
newList.textContent = "Fourth Item";
items.appendChild(newList);
```

In the preceding code, the `ul` element and stored in a variable `items`. Then we create a new `li` element using the createElement method, storing it in a variable newList. We easily add some content to it using the `textElement` method. 

To add `newList` to items, we use the append method while passing `newList` as the parameter. The updated list would be updated to;

```xml
First Item
Second Item
Third Item
Fourth Item
```

## Removing and Replacing Elements

Just as we can select and insert elements into the DOM, we can also easily remove elements from the DOM using the `remove()` method.

For example, let us remove the first item from the list with this method. We would first select the first `li` element using querySelector and store it in a variable `firstItem`.  

```javascript
const firstItem = document.querySelector("li");
firstItem.remove();
document.querySelector("li"); 
```

Using the `remove()` method, we deleted the first list from the HTML list, which would now be updated to:

```xml
Second Item
Third Item
```

In cases where we just want to replace the element and not get rid of them, we can use the `replaceWith()` method.

```javascript
const newList = document.createElement("li");
newList.textContent = "Fourth Item";
const firstItem = document.querySelector("li")
firstItem.replaceWith(newList);
```

The list would be updated to:

```xml
Fourth Item       		
Second Item
Third Item    
```

# Cloning DOM Nodes

We can clone a Node using the `cloneNode()` method. This would return a brand new node and keep the old node.  It takes an optional argument which is a boolean argument that is, either true or false.

By default, it is set at false, and in this case, only the selected element is cloned without any nested element.

```xml
<html>
  		<head>
    			<title>Cloning DOM Nodes</title>
    			<script src="./app.js" defer></script>
  		</head>
  		<body>
     	   <ul class="parent">
        		<li class="child">First Item</li>
       		<li class="child">Second Item</li>
        		<li class="child">Third Item</li>
      	   </ul>
 		</body>
</html>
```

```javascript
const items = document.querySelector("ul");
const clone = items.cloneNode(false);
console.log(clone);
```

The output would be:

```xml
<ul class="parent"> </ul>
```

When the argument is passed as true, all descendants of the selected element will be cloned.

```javascript
const items = document.querySelector("ul");
const clone = items.cloneNode(true);
console.log(clone);
```

The output in the console would be:

```xml
         <ul class="parent">
        		<li class="child">First Item</li>
       		<li class="child">Second Item</li>
        		<li class="child">Third Item</li>
      	 </ul>
```