Javascript: DOM Manipulation 101
Tags: javascript, beginners, tutorial
Published: 2021-02-25 03:01:07

---
title: Javascript: DOM Manipulation 101
published: true
description: 
tags: javascript, beginner, tutorial
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ik1c8mr2sz8zi3g466dq.jpg
series: (Javascript) My learning journey
---

Follow me on Twitter: <a href="https://twitter.com/justericchapman?ref_src=twsrc%5Etfw" class="twitter-follow-button" data-show-count="false">Follow @justericchapman</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<h2>DOM</h2>
Stand for Document Object Model. It's a structured representation of a html document. It allow JS to access html elements and styles to manipulate them.

With JS we can change text, HTML attributes and even CSS style.

DOM exemple
```html
<html>
  <body>
    <div class="message">
      Hello World
    </div>
    <input type="text" id="search" placeholder="search" />
  </body>
</html>
```
In this HTMl document, we have many elements like body, div, input etc.

This HTML document and all his elements can be access and manipulate by JS. 
```js
// Access a DOM element 
const searchInput = document.querySelector('#search')
console.log(searchInput.placeHolder) // Search
```

In the previous example JS use document.querySelector to access a DOM element. DOM element can be select base on many criteria. 

For this request the key '#search' was used. The '#' symbol indicate JS to look in id attributes for a matching key.

document.querySelector('#search') have only one element matching id attributes: 
```html
<input type="text" id="search" placeholder="search" />
```

A reference to this element is place in the searchInput variable.
```js
const searchInput = document.querySelector('#search')
```
Once the reference is set, we can retrieve or change any element attributes.
```js
searchInput.value = 'Hello World' // Will change input value to 'Hello World'
```

Another example will be to select a element with a class name 'message'
```html
<html>
  <body>
    <div class="message">
      Hello World
    </div>
    <input type="text" id="search" placeholder="search" />
  </body>
</html>
```

In this document, only one element have a message class and it's the first div.

The element can be reference using the document.querySelector. But this time we will not use the # symbol but a dot. The dot tell JS to look for a class name match
```js
const divMessage = document.querySelector('.message')
console.log(divMessage.textContent)) // Hello World
divMessage.textContent = 'Hi World' // Change text to Hi World
```

What if I want to access the body tag of my document?
In that case I can use:
```js
const body = document.querySelector('body')
```

So we begin to see a pattern. When we want to select an element we use document.querySelector. This method take one arguments and it's the text we are looking for. This text can have a prefix that specify JS where to look.

```js
// No prefix = look for tag names
document.querySelector('body')

// # prefix = look in id attributes
document.querySelector('#search')

// dot (.) = look in class name 
document.querySelector('.message')
```

Event Listener:
What if we want JS to react to a click event? For example, how to change a message each time a button is click?
```html
<html>
  <body>
    <div class="message">
      This is a message
    </div>
    <input type="text" id="inputMessage" placeholder="Enter a message" />
    <button id="btnChange">Change message</button>
    <script src="main.js"></script>
  </body>
</html>
```
Each time a button is click in the DOM, an event is trigger. We can tell JS to listen to that event and do something when the DOM will trigger this particular event.
```js
// First step, get a reference to the button element
const btnChange = document.querySelector('#btnChange')

// Next create a event listener for the click event
btnChange.addEventListener('click', function() {
  // This function will execute each time the button is click
  const inputMessage = document.querySelector('#inputMessage')
  const message = document.querySelector('.message')
  message.textContent = inputMessage.value
})
```
What if we want to change the message every time the input change. So every keystroke in the input will update the message automatically. No need to use the button.

In that case we will listen to another event. The input have a event call 'input' that is trigger each time input change. We can listen to that even and execute code to update message.

```js
// First step, get a reference to the input field
const inputMessage = document.querySelector('#inputMessage')

// Next create a event listener for the change event
inputMessage.addEventListener('input', function(e) {
  // This function will execute each time the input change 
  const message = document.querySelector('.message')
  // e reference the actual event
  // target reference the event element source (in this case the input field 
  message.textContent = e.target.value
})
```

Global event. How about event that append everywhere on the whole page. Like listening for a key press?
We can use document.addEventListener:
```js
document.addEventListener('keydown', function(e) {
  if (e.key === 'Escape') {
    console.log('Escape key press')
  }
})
```

Change DOM Element style (CCS)
For example we can change the document body background color
```js
// Change to light green background
document.querySelector('body').style.backgroundColor = '#60b250' 
// Hide a element
document.querySelector('.message').style.display = 'none'
// Show a element
document.querySelector('.message').style.display = 'block'
```
Multiple selection:
What to do when more than one element contain for example a class name ".message"?
```html
<html>
  <body>
    <div class="message">
      This is a message
    </div>
    <div class="message">
      This is another message
    </div>
    <div class="message">
      This is last message
    </div>
    
  </body>
</html>
```
If we select using
```js
devMessage = document.querySelector(.message)
```
The querySelector will only return the first ocurence.

What I need to do if I want to select all 3?
Use querySelectorAll:
```js
divMessages = document.querySelectorAll('.message)
```
To access each element we can loop:
```js
for (const element of divMessages) {
  console.log(element.textContent);
}
// or
divMessages.forEach((element) => console.log(element.textContent))
```

Modify element class list:
It is possible to add or remove a class to a element. Here a example div with 2 classes.
```html
<html>
  <body>
    <div class="message hidden">
      This is a message
    </div>
  </body>
</html>
```

We can for example remove the hidden class in JS:
```js
const divMessage = document.querySelector('.message')
divMessage.classList.remove('hidden')
// or you can also add a class
divMessage.classList.add('hidden')

// We can check if a element contain a specific class
if (divMessage.classList.contains('hidden')) {
  // do something
} 
```

Follow me on Twitter: <a href="https://twitter.com/justericchapman?ref_src=twsrc%5Etfw" class="twitter-follow-button" data-show-count="false">Follow @justericchapman</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>