Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 10

Manipulating the DOM

Recommended resources

Hello again! Welcome back to our journey into the Document Object Model.

In our last lesson, you learned the essential skill of selecting any HTML element on a page using querySelector() and querySelectorAll(). You now know how to get a reference to an element, which is the crucial first step.

Today, we'll answer the question, "What can I do with an element once I've selected it?" Our learning outcome is to modify element content, attributes, and styles to dynamically update the UI. This is where your web pages start to feel alive, responding and changing based on your JavaScript code.

We will cover three core manipulation techniques:

  1. Changing Content: How to alter the text and HTML inside an element.
  2. Changing Styles: How to apply CSS styles directly or by managing classes.
  3. Changing Attributes: How to modify attributes like id, src, and custom data-* attributes.

Let's get started!

1. Modifying Element Content

Once you have an element selected, there are three main properties you'll use to change what's inside it: textContent, innerText, and innerHTML.

To get a clear understanding of what each one does and when to use it, let's watch the first few sections of an excellent overview video.

Learn DOM Manipulation In 18 Minutes

The video 'Learn DOM Manipulation In 18 Minutes' from Web Dev Simplified provides a concise tour of the most common DOM manipulation techniques. We'll start with the sections on content.

Watch from 03:59 to 09:45. Pay close attention to: The difference between innerText and textContent, especially regarding CSS visibility and spacing. How innerHTML is used to render HTML tags. The security warning associated with innerHTML and the safer alternative.

Key Differences: textContent vs. innerText vs. innerHTML

As the video explained, here’s a quick summary:

  • textContent: Gets the content of all elements, including <script> and <style> elements. It returns a string with all the text, preserving spacing and including text from hidden elements. It's generally fast and predictable.
  • innerText: This property is "human-readable" and aware of the rendered appearance. It won't return text from hidden elements and normalizes spacing. It's slower than textContent because it has to consider the layout.
  • innerHTML: This property gets or sets the HTML markup contained within an element. When you set it, the browser re-parses the string as HTML.

General Rule of Thumb:

  • To change only the text of an element, use textContent. It's the safest and most performant option.
  • Only use innerHTML when you explicitly need to render HTML from a string. Be extremely careful with user-provided input to avoid Cross-Site Scripting (XSS) attacks. Never set innerHTML with a value that came from a user.

Let's try a quick example. Given this HTML:

<div id="greeting">Hello, <span>World</span>!</div>

Here's how these properties would behave:

const greetingDiv = document.querySelector('#greeting');

// Change the text
greetingDiv.textContent = "Welcome to the page!"; 
// HTML becomes: <div id="greeting">Welcome to the page!</div>
// The <span> is gone.

// Add bold text
greetingDiv.innerHTML = "You are <b>AWESOME</b>!";
// HTML becomes: <div id="greeting">You are <b>AWESOME</b>!</div>
// The <b> tag is rendered by the browser.

2. Modifying Element Styles

Dynamically changing styles is key to providing visual feedback to users. For example, highlighting a selected item, showing a validation error, or switching to a dark mode. There are two primary ways to do this.

Method 1: Direct Inline Styles (The .style Property)

Every element object has a style property. You can use this to set any CSS property directly on the element, which results in an inline style in the HTML (<div style="color: red;">).

A key detail to remember is that CSS properties with hyphens (e.g., background-color) must be converted to camelCase in JavaScript (e.g., backgroundColor).

Let's see this in action.

Learn DOM Manipulation In 18 Minutes

Continuing with the 'Learn DOM Manipulation' video, this short clip shows how to use the .style property and the camelCase convention.

Watch from 17:28 to 18:14. Notice how background-color is written as backgroundColor in the JavaScript code.

Example:

const title = document.querySelector('h1');

title.style.color = 'blue';
title.style.fontSize = '48px'; // Note: the value is a string
title.style.textDecoration = 'underline';

While direct styling is quick for simple changes, it mixes your styling rules with your application logic, which can become hard to manage. For anything more complex, the second method is preferred.

Method 2: Managing Classes (The .classList Property)

A much cleaner and more scalable approach is to define your styles in your CSS file using classes and then use JavaScript to add, remove, or toggle those classes on your elements. This follows the principle of separation of concerns.

The classList property provides easy-to-use methods for this:

  • element.classList.add('my-class')
  • element.classList.remove('my-class')
  • element.classList.toggle('my-class') (Adds the class if it's not there, removes it if it is)

This is the most common and recommended way to handle dynamic styling.

Learn DOM Manipulation In 18 Minutes

Let's watch the section on classList from the same video. This is one of the most useful tools for DOM manipulation.

Watch from 16:10 to 17:28. The presenter covers adding, removing, and toggling classes.

You can find a great text-based summary of these methods in the freeCodeCamp article "How to Manipulate the DOM in JavaScript". It's a good resource to bookmark for quick reference.

Test your understanding!

Imagine you have a CSS file with .error { color: red; border: 1px solid red; }.

Given the HTML <input type="text" id="username">, how would you write JavaScript to apply the error style to the input field? Which method (.style or .classList) is more appropriate here and why?

Show answer

The classList method is more appropriate.

const usernameInput = document.querySelector('#username');
usernameInput.classList.add('error');

This is better because it keeps the styling definition (color and border) in the CSS file. If you wanted to change the error style later (e.g., add a background color), you would only need to update the CSS, not your JavaScript code. Using .style would require two separate lines of JS and would hard-code the style rules in your script.


3. Modifying Element Attributes

You'll often need to change HTML attributes dynamically. For example, changing the src of an <img> tag, the href of an <a> tag, or the disabled state of a <button>.

Standard Attributes

You can use getAttribute(), setAttribute(), and removeAttribute() for this.

  • element.setAttribute('attributeName', 'value'): Sets the value of an attribute. If the attribute doesn't exist, it's created.
  • element.getAttribute('attributeName'): Returns the current value of an attribute.
  • element.removeAttribute('attributeName'): Removes an attribute completely.

Some common attributes can also be accessed as direct properties (e.g., img.src, a.href, input.value), but setAttribute works for everything.

Learn DOM Manipulation In 18 Minutes

This next section of the video demonstrates how to work with standard attributes.

Watch from 11:37 to 13:40. Observe how setAttribute can change an element's id and title.

Custom Data Attributes (dataset)

A very powerful feature of modern HTML is the ability to store extra, custom information on an element using data-* attributes. These are incredibly useful for linking DOM elements to data in your JavaScript without polluting class names or IDs.

For any attribute that starts with data-, you can access it through the element's dataset property. The data- prefix is removed, and the rest of the attribute name is converted to camelCase.

  • HTML: <div data-user-id="123" data-role="admin">
  • JS: div.dataset.userId would be "123" and div.dataset.role would be "admin".

You can also set these attributes directly in JavaScript: div.dataset.lastLogin = '2023-10-27'; will add a data-last-login="2023-10-27" attribute to the HTML.

Learn DOM Manipulation In 18 Minutes

Let's watch the final relevant clip, which covers the very useful dataset property.

Watch from 13:40 to 16:10. This is a modern technique you will see often, especially when you start working with frameworks.


Practice Exercise

Now, let's put all these pieces together.

  1. Create two files in a folder: index.html and script.js.
  2. Copy the following code into index.html:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>DOM Manipulation Practice</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>

    <h1 id="main-title">Original Title</h1>
    <p class="description">This is the original description.</p>
    
    <div id="status-card" data-status="pending">
        <p>Status: <span id="status-text">Pending</span></p>
    </div>
    
    <button id="update-btn">Update Status</button>

    <script src="script.js"></script>
</body>
</html>
  1. Create a style.css file and add these styles:
.card-success {
    border: 2px solid green;
    background-color: #e6ffe6;
    padding: 10px;
}

.status-text-success {
    color: green;
    font-weight: bold;
}
  1. Now, in your script.js file, write the JavaScript code to perform the following tasks:
    a. Select the <h1> with the ID main-title and change its textContent to "Welcome to the Interactive Page!".
    b. Select the <p> with the class description and use the .style property to change its font style to italic.
    c. Select the div with the ID status-card. Change its data-status attribute to "approved" using setAttribute.
    d. Select the <span> with the ID status-text. Change its textContent to "Approved".
    e. Add the class card-success to the status-card div and the class status-text-success to the status-text span using classList.

Open index.html in your browser. If you've done everything correctly, the title and description should be updated, and the status card should have a green border and green text.

Show Solution
// script.js

// Task a
const mainTitle = document.querySelector('#main-title');
mainTitle.textContent = "Welcome to the Interactive Page!";

// Task b
const description = document.querySelector('.description');
description.style.fontStyle = 'italic';

// Task c
const statusCard = document.querySelector('#status-card');
statusCard.setAttribute('data-status', 'approved');

// Task d
const statusText = document.querySelector('#status-text');
statusText.textContent = 'Approved';

// Task e
statusCard.classList.add('card-success');
statusText.classList.add('status-text-success');

Conclusion

Great work! You've just mastered the fundamental techniques for making a web page dynamic. This is the core skill set you'll use constantly as a web developer.

Key Takeaways:

  • Content: Use textContent for safely changing text, and innerHTML with caution when you need to render HTML.
  • Styles: The style property is for quick, direct changes, but using classList to add/remove predefined CSS classes is the more robust and maintainable method. Remember to convert CSS properties to camelCase when using the style property.
  • Attributes: setAttribute() and its counterparts are reliable for any attribute, while the dataset property provides a clean, modern way to work with custom data-* attributes.

In the next lesson, "Create, append, and remove DOM elements," we'll take this a step further. Instead of just modifying existing elements, you'll learn how to create brand new elements entirely with JavaScript and add them to (or remove them from) the page. This will unlock the ability to build truly dynamic user interfaces, like adding new items to a list or showing new content in response to user actions.