DEV Community

Cover image for Javascript: DOM Manipulation 101
Eric The Coder
Eric The Coder

Posted on • Edited on

Javascript: DOM Manipulation 101

Follow me on Twitter: Follow @justericchapman

DOM

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>
  <body>
    <div class="message">
      Hello World
    </div>
    <input type="text" id="search" placeholder="search" />
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

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.

// Access a DOM element 
const searchInput = document.querySelector('#search')
console.log(searchInput.placeHolder) // Search
Enter fullscreen mode Exit fullscreen mode

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:

<input type="text" id="search" placeholder="search" />
Enter fullscreen mode Exit fullscreen mode

A reference to this element is place in the searchInput variable.

const searchInput = document.querySelector('#search')
Enter fullscreen mode Exit fullscreen mode

Once the reference is set, we can retrieve or change any element attributes.

searchInput.value = 'Hello World' // Will change input value to 'Hello World'
Enter fullscreen mode Exit fullscreen mode

Another example will be to select a element with a class name 'message'

<html>
  <body>
    <div class="message">
      Hello World
    </div>
    <input type="text" id="search" placeholder="search" />
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

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

const divMessage = document.querySelector('.message')
console.log(divMessage.textContent)) // Hello World
divMessage.textContent = 'Hi World' // Change text to Hi World
Enter fullscreen mode Exit fullscreen mode

What if I want to access the body tag of my document?
In that case I can use:

const body = document.querySelector('body')
Enter fullscreen mode Exit fullscreen mode

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.

// 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')
Enter fullscreen mode Exit fullscreen mode

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>
  <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>
Enter fullscreen mode Exit fullscreen mode

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.

// 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
})
Enter fullscreen mode Exit fullscreen mode

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.

// 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
})
Enter fullscreen mode Exit fullscreen mode

Global event. How about event that append everywhere on the whole page. Like listening for a key press?
We can use document.addEventListener:

document.addEventListener('keydown', function(e) {
  if (e.key === 'Escape') {
    console.log('Escape key press')
  }
})
Enter fullscreen mode Exit fullscreen mode

Change DOM Element style (CCS)
For example we can change the document body background color

// 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'
Enter fullscreen mode Exit fullscreen mode

Multiple selection:
What to do when more than one element contain for example a class name ".message"?

<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>
Enter fullscreen mode Exit fullscreen mode

If we select using

devMessage = document.querySelector(.message)
Enter fullscreen mode Exit fullscreen mode

The querySelector will only return the first ocurence.

What I need to do if I want to select all 3?
Use querySelectorAll:

divMessages = document.querySelectorAll('.message)
Enter fullscreen mode Exit fullscreen mode

To access each element we can loop:

for (const element of divMessages) {
  console.log(element.textContent);
}
// or
divMessages.forEach((element) => console.log(element.textContent))
Enter fullscreen mode Exit fullscreen mode

Modify element class list:
It is possible to add or remove a class to a element. Here a example div with 2 classes.

<html>
  <body>
    <div class="message hidden">
      This is a message
    </div>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

We can for example remove the hidden class in 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
} 
Enter fullscreen mode Exit fullscreen mode

Follow me on Twitter: Follow @justericchapman

Top comments (1)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.