JavaScript DOM Manipulation: Find and Change HTML Elements

JavaScript DOM manipulation lets you find HTML elements and change what appears on a webpage.

You can change text, update styles, add or remove classes, create new elements, change attributes, hide content, or remove elements from the page.

This is where JavaScript starts to feel like real frontend development because your code can now change the webpage that users see.

Course Home: JavaScript Tutorial for Beginners
Previous Lesson: JavaScript Objects Explained
Next Lesson: JavaScript Events Explained for Beginners

Quick Answer

The DOM represents an HTML page as objects that JavaScript can access.

For example, this HTML:

<h1 id="title">Hello</h1>

can be selected with JavaScript:

const title = document.querySelector("#title");

Then you can change its text:

title.textContent = "Welcome";

The webpage now shows:

Welcome

Common DOM tasks include:

  • Finding elements
  • Reading and changing text
  • Changing HTML
  • Adding and removing classes
  • Changing styles
  • Reading and changing attributes
  • Creating new elements
  • Adding elements to the page
  • Removing elements

What Is the DOM in JavaScript?

DOM stands for Document Object Model.

When a browser loads an HTML page, it creates a structured representation of that page.

JavaScript can use this structure to work with HTML elements.

For example, HTML may contain:

<h1>JavaScript Tutorial</h1>
<p>Learn JavaScript step by step.</p>

The browser makes these elements available through the DOM.

JavaScript can then find the heading, read its text, change it, add classes, remove it, or create new elements around it.

Why DOM Manipulation Matters

Without DOM manipulation, JavaScript could calculate values and process data, but it would not be able to update the visible webpage directly.

DOM manipulation lets you build features such as:

  • Mobile menus
  • Accordions
  • Tabs
  • Modals
  • Product filters
  • Shopping carts
  • Live counters
  • Form messages
  • Validation feedback
  • To-do lists
  • Image galleries
  • Dropdowns
  • Dynamic dashboards

Most interactive website features depend on the DOM together with JavaScript events.

The document Object

The browser provides the:

document

object for the current webpage.

For example:

console.log(document);

This gives access to the HTML document.

You will commonly use methods such as:

document.querySelector()
document.querySelectorAll()
document.getElementById()
document.createElement()

to work with page elements.

Start With Simple HTML

Use this HTML for the first examples:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>DOM Example</title>

    <script src="script.js" defer></script>
</head>
<body>

    <h1 id="title">Hello</h1>
    <p class="message">Welcome to the page.</p>

</body>
</html>

The JavaScript goes inside:

script.js

Using defer lets the browser parse the HTML before the script runs.

If this setup is unfamiliar, review How to Add JavaScript to HTML.

Find an Element With getElementById()

Use:

document.getElementById()

when you want an element with a specific id.

HTML:

<h1 id="title">Hello</h1>

JavaScript:

const title = document.getElementById("title");

console.log(title);

The method receives the ID without #.

Use:

"title"

not:

"#title"

with getElementById().

Find an Element With querySelector()

querySelector() uses CSS selector syntax.

HTML:

<h1 id="title">Hello</h1>

JavaScript:

const title = document.querySelector("#title");

Because this is a CSS ID selector, it uses:

#

You can also select a class:

const message = document.querySelector(".message");

Or an element:

const heading = document.querySelector("h1");

querySelector() Returns the First Match

Suppose your HTML contains:

<p class="message">First</p>
<p class="message">Second</p>

This:

const message = document.querySelector(".message");

selects only the first matching element.

To select all matches, use:

document.querySelectorAll()

Select Multiple Elements With querySelectorAll()

HTML:

<p class="message">First</p>
<p class="message">Second</p>
<p class="message">Third</p>

JavaScript:

const messages = document.querySelectorAll(".message");

console.log(messages);

querySelectorAll() returns a NodeList.

You can loop through it:

for (const message of messages) {
    console.log(message.textContent);
}

Output:

First
Second
Third

This works naturally with what you learned in the JavaScript Loops tutorial.

getElementById() vs querySelector()

Both can find an element by ID.

Example with getElementById():

const title = document.getElementById("title");

Example with querySelector():

const title = document.querySelector("#title");

Use getElementById() when you specifically want one element by ID.

Use querySelector() when CSS selector flexibility makes the code easier.

querySelector() can work with:

  • IDs
  • Classes
  • Element names
  • Attributes
  • Nested selectors
  • More complex CSS selectors

Common querySelector Examples

Find an ID:

document.querySelector("#menu");

Find a class:

document.querySelector(".card");

Find the first button:

document.querySelector("button");

Find a button inside a form:

document.querySelector("form button");

Find an input by attribute:

document.querySelector('input[type="email"]');

CSS selector knowledge is very useful when working with the DOM.

What Happens When No Element Is Found?

If querySelector() cannot find a matching element, it returns:

null

Example:

const element = document.querySelector("#doesNotExist");

console.log(element);

Output:

null

Trying to use a property on null can cause an error.

For example:

element.textContent = "Hello";

fails because there is no matching element.

Check an Element Before Using It

When an element may not exist:

const banner = document.querySelector("#banner");

if (banner) {
    banner.textContent = "Welcome";
}

This changes the element only when it was found.

You can also use optional chaining in some cases:

document.querySelector("#banner")?.classList.add("active");

You learned optional chaining in the JavaScript Objects tutorial.

Read Text With textContent

HTML:

<h1 id="title">JavaScript Tutorial</h1>

JavaScript:

const title = document.querySelector("#title");

console.log(title.textContent);

Output:

JavaScript Tutorial

textContent reads the text content of an element.

Change Text With textContent

Example:

const title = document.querySelector("#title");

title.textContent = "Learn JavaScript";

The heading changes on the page.

Before:

<h1 id="title">JavaScript Tutorial</h1>

After the change, the visible text becomes:

Learn JavaScript

Real Website Example: Cart Count

HTML:

<span id="cartCount">0</span>

JavaScript:

const cartCount = document.querySelector("#cartCount");

let quantity = 3;

cartCount.textContent = quantity;

The page now shows:

3

This is a simple example of connecting JavaScript data to visible HTML.

textContent vs innerText

You may see both:

element.textContent

and:

element.innerText

They are not exactly the same.

textContent works with the text content of the node and its descendants.

innerText is influenced by rendered layout and visibility.

For many simple text updates, textContent is a clear and reliable choice.

Read HTML With innerHTML

Suppose:

<div id="message">
    <strong>Hello</strong>
</div>

JavaScript:

const message = document.querySelector("#message");

console.log(message.innerHTML);

The result contains the HTML inside the element:

<strong>Hello</strong>

Change HTML With innerHTML

You can replace the HTML inside an element.

const message = document.querySelector("#message");

message.innerHTML = "<strong>Welcome</strong>";

The element now contains a element.

Be Careful With innerHTML

innerHTML can parse text as HTML.

That makes it useful, but also risky when the value comes from users or untrusted external data.

Avoid doing this with untrusted input:

message.innerHTML = userInput;

For normal text, prefer:

message.textContent = userInput;

This treats the value as text instead of parsing it as HTML.

When you need to build structured elements, createElement() is often a safer and clearer approach.

textContent vs innerHTML

Use:

textContent

when you need plain text.

Use:

innerHTML

only when you intentionally need to read or insert HTML markup and the content is trusted.

Example:

element.textContent = "<strong>Hello</strong>";

shows the markup as text.

But:

element.innerHTML = "<strong>Hello</strong>";

creates a real element.

Change an Element’s Style

You can access inline styles through:

element.style

Example:

const title = document.querySelector("#title");

title.style.fontSize = "40px";

You can also write:

title.style.display = "none";

or:

title.style.marginTop = "20px";

CSS properties containing hyphens usually become camelCase in JavaScript.

For example:

background-color

becomes:

backgroundColor

Should You Change Many Styles With JavaScript?

For one small dynamic value, inline style changes can be useful.

For several style changes, CSS classes are usually easier to maintain.

Instead of:

element.style.fontSize = "20px";
element.style.fontWeight = "700";
element.style.padding = "10px";

you can create a CSS class and add that class with JavaScript.

This keeps styling in CSS and behavior in JavaScript.

Add a CSS Class With classList.add()

HTML:

<div id="alert">Saved</div>

CSS:

.success {
    font-weight: 700;
    padding: 10px;
}

JavaScript:

const alertBox = document.querySelector("#alert");

alertBox.classList.add("success");

The element now has the success class.

Remove a Class With classList.remove()

alertBox.classList.remove("success");

This removes the class.

Toggle a Class With classList.toggle()

toggle() adds a class when it is missing and removes it when it is present.

Example:

const menu = document.querySelector("#menu");

menu.classList.toggle("open");

This is useful for:

  • Mobile menus
  • Dropdowns
  • Accordions
  • Modals
  • Dark mode
  • Active states

Real Website Example: Mobile Menu

HTML:

<button id="menuButton">Menu</button>

<nav id="menu" class="menu">
    <a href="/">Home</a>
    <a href="/about">About</a>
</nav>

CSS:

.menu {
    display: none;
}

.menu.open {
    display: block;
}

JavaScript:

const menu = document.querySelector("#menu");

menu.classList.add("open");

This opens the menu by adding a CSS class.

In the next lesson, you will make this happen when the button is clicked using JavaScript events.

Check Whether a Class Exists

Use:

classList.contains()

Example:

const menu = document.querySelector("#menu");

console.log(menu.classList.contains("open"));

The result is:

true

or:

false

depending on whether the class exists.

Replace a Class

You can use:

classList.replace()

Example:

element.classList.replace("loading", "complete");

This replaces one class with another when the old class exists.

Read an Attribute With getAttribute()

HTML:

<a id="websiteLink" href="/about/">About</a>

JavaScript:

const link = document.querySelector("#websiteLink");

console.log(link.getAttribute("href"));

Output:

/about/

Change an Attribute With setAttribute()

Example:

link.setAttribute("href", "/contact/");

Now the link points to:

/contact/

You can set other attributes too:

link.setAttribute("title", "Contact us");

Remove an Attribute

Use:

removeAttribute()

Example:

link.removeAttribute("title");

The title attribute is removed.

Check Whether an Attribute Exists

Use:

hasAttribute()

Example:

console.log(link.hasAttribute("href"));

Output:

true

DOM Properties vs HTML Attributes

Many common HTML attributes also have DOM properties.

For example:

<input id="email" value="user@example.com">

JavaScript can read:

const email = document.querySelector("#email");

console.log(email.value);

For form fields, properties such as:

value
checked
disabled

are often more useful than reading the original HTML attribute.

You will work with these in the JavaScript Form Validation tutorial.

Change an Image Source

HTML:

<img id="productImage" src="image-1.jpg" alt="Product">

JavaScript:

const productImage = document.querySelector("#productImage");

productImage.src = "image-2.jpg";

You can also update the alt text:

productImage.alt = "Black wireless keyboard";

This is useful for galleries, product variations, and dynamic content.

HTML:

<a id="ctaLink" href="/old-page/">Learn More</a>

JavaScript:

const ctaLink = document.querySelector("#ctaLink");

ctaLink.href = "/javascript-tutorial/";

You can also change its text:

ctaLink.textContent = "Start JavaScript Tutorial";

Create an Element With createElement()

Use:

document.createElement()

to create a new HTML element.

Example:

const paragraph = document.createElement("p");

This creates a paragraph element in memory.

It is not visible on the page yet.

Add text:

paragraph.textContent = "New paragraph";

Now you need to insert it into the document.

Add an Element With append()

Suppose the HTML contains:

<div id="content"></div>

JavaScript:

const content = document.querySelector("#content");

const paragraph = document.createElement("p");
paragraph.textContent = "New paragraph";

content.append(paragraph);

The paragraph is now added inside the content element.

append() Can Add More Than One Item

Example:

const first = document.createElement("p");
first.textContent = "First";

const second = document.createElement("p");
second.textContent = "Second";

content.append(first, second);

Both elements are added.

append() can also append text strings.

appendChild()

You may also see:

appendChild()

Example:

content.appendChild(paragraph);

It adds one node as the last child.

Both append() and appendChild() are common.

For many modern beginner examples, append() is flexible and easy to use.

Add an Element at the Beginning With prepend()

Use:

prepend()

to insert content at the beginning.

Example:

const heading = document.createElement("h2");
heading.textContent = "Products";

content.prepend(heading);

The heading becomes the first child inside content.

Insert an Element Before or After Another Element

Modern DOM methods include:

before()
after()

Example:

const title = document.querySelector("#title");

const note = document.createElement("p");
note.textContent = "Read this first.";

title.after(note);

The paragraph is inserted immediately after the title.

Real Website Example: Create a Product Card

Suppose:

const product = {
    name: "Keyboard",
    price: 1500
};

HTML:

<div id="products"></div>

JavaScript:

const productsContainer = document.querySelector("#products");

const card = document.createElement("article");
const title = document.createElement("h2");
const price = document.createElement("p");

title.textContent = product.name;
price.textContent = `₹${product.price}`;

card.append(title, price);
productsContainer.append(card);

This creates a product card using JavaScript.

No HTML string is required.

Create Several Elements From an Array

Suppose:

const products = [
    "Laptop",
    "Phone",
    "Tablet"
];

HTML:

<ul id="productList"></ul>

JavaScript:

const productList = document.querySelector("#productList");

for (const product of products) {
    const item = document.createElement("li");

    item.textContent = product;

    productList.append(item);
}

The page receives three list items.

This combines DOM manipulation with JavaScript arrays and JavaScript loops.

Create Product Cards From an Array of Objects

Suppose:

const products = [
    { name: "Laptop", price: 50000 },
    { name: "Phone", price: 25000 },
    { name: "Mouse", price: 1000 }
];

HTML:

<div id="products"></div>

JavaScript:

const productsContainer = document.querySelector("#products");

for (const product of products) {
    const card = document.createElement("article");
    const name = document.createElement("h2");
    const price = document.createElement("p");

    name.textContent = product.name;
    price.textContent = `₹${product.price}`;

    card.append(name, price);
    productsContainer.append(card);
}

This pattern is much closer to real frontend development.

Later, the product data may come from an API instead of being written directly in the script.

Remove an Element With remove()

HTML:

<p id="message">Temporary message</p>

JavaScript:

const message = document.querySelector("#message");

message.remove();

The element is removed from the DOM.

Remove a Child Element

You may also see older or parent-based code such as:

parent.removeChild(child);

For removing a known element directly, this is often simpler:

element.remove();

Replace an Element

Use:

replaceWith()

Example:

const oldMessage = document.querySelector("#message");

const newMessage = document.createElement("p");
newMessage.textContent = "Updated message";

oldMessage.replaceWith(newMessage);

The old element is replaced with the new one.

Clone an Element

Use:

cloneNode()

Example:

const card = document.querySelector(".card");

const copy = card.cloneNode(true);

The argument:

true

means child content is also cloned.

A shallow clone uses:

false

Be careful with cloned IDs because duplicate IDs can create invalid page structure and selector problems.

Parent and Child DOM Relationships

HTML elements form a tree.

Example:

<section id="products">
    <article class="card">
        <h2>Keyboard</h2>
    </article>
</section>

The section is the parent of the article.

The article is the parent of the heading.

JavaScript provides properties for moving through these relationships.

Get the Parent Element

Example:

const card = document.querySelector(".card");

console.log(card.parentElement);

This returns the parent element.

Get Child Elements

Example:

const products = document.querySelector("#products");

console.log(products.children);

children returns the element children.

Access the first:

console.log(products.children[0]);

firstElementChild and lastElementChild

Example:

console.log(products.firstElementChild);
console.log(products.lastElementChild);

These give the first and last child elements.

Previous and Next Element Siblings

You can move between sibling elements:

element.previousElementSibling

and:

element.nextElementSibling

These are useful when components contain related nearby elements.

Find the Closest Matching Parent

Use:

closest()

Example:

const button = document.querySelector(".buy-button");

const card = button.closest(".product-card");

This searches the element and its ancestors for the nearest match.

closest() becomes very useful with events and repeated cards.

Find Descendants Inside One Element

Selectors can start from an element instead of the whole document.

Example:

const card = document.querySelector(".product-card");

const title = card.querySelector(".product-title");

This finds .product-title only inside that card.

This is useful when several components use the same class names.

data-* Attributes

HTML can store custom data with data-* attributes.

Example:

<button
    class="buy-button"
    data-product-id="101"
    data-product-name="Keyboard"
>
    Add to Cart
</button>

JavaScript can read them through:

const button = document.querySelector(".buy-button");

console.log(button.dataset.productId);
console.log(button.dataset.productName);

Output:

101
Keyboard

data-product-id becomes:

dataset.productId

This is useful for connecting HTML elements to product IDs, tabs, modal targets, and other application data.

Change a data Attribute

You can update:

button.dataset.productId = "102";

The related HTML data value changes.

Use data attributes for custom element metadata, not as a replacement for all application state.

Hide an Element With hidden

HTML elements have a hidden property.

Example:

const message = document.querySelector("#message");

message.hidden = true;

This hides the element.

Show it again:

message.hidden = false;

Toggle it:

message.hidden = !message.hidden;

This is a clean option for simple show-and-hide behavior.

Real Website Example: Empty Cart Message

HTML:

<p id="emptyMessage">Your cart is empty.</p>

JavaScript:

const emptyMessage = document.querySelector("#emptyMessage");

const cart = ["Keyboard"];

emptyMessage.hidden = cart.length > 0;

Because the cart has an item, the empty-cart message is hidden.

Change Form Input Values

HTML:

<input id="name" type="text">

JavaScript:

const nameInput = document.querySelector("#name");

nameInput.value = "Riya";

Read it:

console.log(nameInput.value);

Output:

Riya

Form controls have useful properties such as:

value
checked
disabled
selected

You will use these more deeply in form validation.

Checkbox checked Property

HTML:

<input id="terms" type="checkbox">

JavaScript:

const terms = document.querySelector("#terms");

console.log(terms.checked);

The result is a boolean.

You can also change it:

terms.checked = true;

Disable a Button

HTML:

<button id="submitButton">Submit</button>

JavaScript:

const submitButton = document.querySelector("#submitButton");

submitButton.disabled = true;

Enable it again:

submitButton.disabled = false;

This is useful when a form is incomplete or while data is being submitted.

Real Website Example: Update a Price

HTML:

<p id="price">₹1500</p>

JavaScript:

const priceElement = document.querySelector("#price");

const product = {
    price: 1200
};

priceElement.textContent = `₹${product.price}`;

The page now shows:

₹1200

DOM manipulation often connects JavaScript objects to visible page content.

Real Website Example: Show a Sale Badge

HTML:

<div id="product">
    <h2>Keyboard</h2>
</div>

JavaScript:

const productElement = document.querySelector("#product");

const saleBadge = document.createElement("span");
saleBadge.textContent = "Sale";
saleBadge.classList.add("sale-badge");

productElement.append(saleBadge);

The badge is created and added dynamically.

Real Website Example: Update User Profile

HTML:

<h2 id="userName"></h2>
<p id="userCity"></p>

JavaScript:

const user = {
    name: "Riya",
    city: "Delhi"
};

const userName = document.querySelector("#userName");
const userCity = document.querySelector("#userCity");

userName.textContent = user.name;
userCity.textContent = user.city;

This is a basic example of rendering object data into the page.

Real Website Example: Render a List

HTML:

<ul id="skills"></ul>

JavaScript:

const skills = ["HTML", "CSS", "JavaScript"];

const skillsList = document.querySelector("#skills");

for (const skill of skills) {
    const item = document.createElement("li");

    item.textContent = skill;

    skillsList.append(item);
}

The webpage receives:

HTML
CSS
JavaScript

Clearing Existing Content

Suppose a list already has items.

One simple way to remove text and child elements is:

list.replaceChildren();

You can then add fresh elements.

Example:

const list = document.querySelector("#productList");

list.replaceChildren();

This removes all existing children.

Another common approach is:

list.textContent = "";

Both can clear simple container content.

replaceChildren() With New Elements

You can replace existing children with new nodes:

const first = document.createElement("li");
first.textContent = "Laptop";

const second = document.createElement("li");
second.textContent = "Phone";

list.replaceChildren(first, second);

The old children are removed and the new ones are inserted.

DocumentFragment for Several New Elements

When building several DOM nodes, you may see:

document.createDocumentFragment()

Example:

const fragment = document.createDocumentFragment();

for (const product of products) {
    const item = document.createElement("li");

    item.textContent = product;

    fragment.append(item);
}

productList.append(fragment);

A document fragment lets you prepare several nodes before inserting them into the document.

Modern browsers already optimize many DOM operations, so do not use fragments mechanically for every tiny list. They are useful to understand when building larger batches of nodes.

DOM Manipulation and Performance

DOM work can be more expensive than normal JavaScript calculations because it can affect page rendering.

For beginner projects, focus first on clear code.

As your applications grow:

  • Avoid repeatedly searching for the same element when you can store the reference.
  • Group related updates when practical.
  • Do not rebuild large page sections without need.
  • Avoid reading and writing layout-related styles repeatedly in tight loops.
  • Use CSS classes for groups of style changes.

Example:

const menu = document.querySelector("#menu");

Store that reference when you will use the same element several times.

Store Element References in Variables

Instead of repeating:

document.querySelector("#title").textContent = "Welcome";
document.querySelector("#title").classList.add("active");

prefer:

const title = document.querySelector("#title");

title.textContent = "Welcome";
title.classList.add("active");

The code is shorter and easier to read.

DOM Manipulation vs JavaScript Data

Keep your application data separate from visible HTML when practical.

For example:

const cart = [
    { name: "Keyboard", quantity: 2 }
];

This is application data.

Then DOM code can display it:

cartCount.textContent = cart.length;

Avoid treating the DOM as the only place where important application data exists.

This becomes especially important in larger frontend applications.

DOM Manipulation and Events

DOM manipulation changes the page.

Events decide when those changes happen.

For example:

const menu = document.querySelector("#menu");

menu.classList.toggle("open");

changes the menu immediately when that line runs.

To make it happen after a click, you need an event listener:

menuButton.addEventListener("click", () => {
    menu.classList.toggle("open");
});

That is the focus of the next JavaScript Events lesson.

Common Beginner Mistakes

Using # With getElementById()

Wrong:

document.getElementById("#title");

Correct:

document.getElementById("title");

getElementById() receives the ID name without #.

Forgetting # With querySelector()

If selecting an ID:

document.querySelector("#title");

The # is required because querySelector() uses CSS selector syntax.

Forgetting . for a Class Selector

Wrong:

document.querySelector("message");

when the HTML contains:

<p class="message">Hello</p>

Use:

document.querySelector(".message");

Using querySelector() When You Need Every Match

This returns only the first matching element:

document.querySelector(".card");

Use:

document.querySelectorAll(".card");

when you need all matching elements.

Using an Element Before It Exists

If a script runs before the HTML element is parsed, your selector may return null.

A good beginner setup is:

<script src="script.js" defer></script>

Review How to Add JavaScript to HTML for script loading details.

Ignoring a null Selector Result

This can fail:

const title = document.querySelector("#wrongId");

title.textContent = "Hello";

Check the selector spelling or guard the element when it may not exist.

Using innerHTML for Untrusted Text

Avoid:

element.innerHTML = userInput;

when userInput is not trusted HTML.

Prefer:

element.textContent = userInput;

for plain user-provided text.

Changing Too Many Inline Styles

This works:

element.style.fontSize = "20px";
element.style.fontWeight = "700";
element.style.padding = "10px";

But a CSS class is often cleaner:

element.classList.add("highlighted");

Forgetting camelCase for style Properties

Wrong:

element.style.background-color = "red";

Correct:

element.style.backgroundColor = "red";

Creating an Element but Never Adding It

This only creates the element:

const item = document.createElement("li");

It is not visible yet.

You still need something such as:

list.append(item);

Confusing append() With Replacing Content

append() adds new content.

Calling it repeatedly keeps adding more nodes.

If you want fresh content each time, clear or replace the existing children first.

Creating Duplicate IDs

Do not create several elements with the same ID.

IDs should identify one element in the page.

For repeated cards or list items, use classes or data attributes instead.

Treating an Empty NodeList Like null

querySelectorAll() returns a NodeList.

When nothing matches, it returns an empty NodeList rather than null.

You can check:

const cards = document.querySelectorAll(".card");

console.log(cards.length);

A length of 0 means no matches.

Expecting typeof an Element to Explain Its Exact Type

DOM elements are objects.

Instead of relying on typeof, work with their DOM properties, methods, selectors, and element classes.

Best Practices for JavaScript DOM Manipulation

Use clear selectors.

Prefer IDs for unique elements and classes for repeated components.

Store frequently used element references in variables.

Use textContent for plain text.

Use innerHTML only when you intentionally need trusted HTML markup.

Prefer CSS classes over many inline style changes.

Use classList.add(), remove(), toggle(), and contains() for class changes.

Use createElement() when building structured content from data.

Check for null when an element may not exist.

Use Array.isArray() for JavaScript arrays and do not confuse arrays with DOM collections.

Keep your application data separate from the DOM when practical.

Use semantic HTML first, then enhance it with JavaScript.

Avoid unnecessary DOM updates inside large loops.

Keep accessibility in mind when changing visibility, labels, buttons, and interactive controls.

Beginner Exercise

Use this HTML:

<h1 id="title">Old Title</h1>

<p class="message">Old message</p>

<ul id="skills"></ul>

Complete these tasks with JavaScript:

  1. Change the heading to JavaScript DOM Practice.
  2. Change the paragraph to DOM manipulation is working.
  3. Add a class named active to the heading.
  4. Create three
  5. elements.
  6. Add HTML, CSS, and JavaScript as list items.
  7. Append the items to the skills list.
  8. Print the final number of list items.

Try to complete the task without using innerHTML.

Challenge Exercise

Use this product data:

const products = [
    {
        name: "Keyboard",
        price: 1500,
        inStock: true
    },
    {
        name: "Mouse",
        price: 700,
        inStock: false
    },
    {
        name: "Monitor",
        price: 12000,
        inStock: true
    }
];

And this HTML:

<div id="products"></div>

Create one product card for every object.

Each card should contain:

  • Product name
  • Price
  • Stock message

Show:

In stock

when inStock is true.

Show:

Out of stock

when it is false.

Create the elements with:

document.createElement()

and add them with:

append()

Extra Challenge

Add a CSS class:

out-of-stock

only to unavailable product cards.

Do this with:

classList.add()

Do not add the class to products that are available.

Frequently Asked Questions

What is DOM manipulation in JavaScript?

DOM manipulation means using JavaScript to find, read, create, change, or remove elements in an HTML document.

What does DOM stand for?

DOM stands for Document Object Model.

It represents the webpage as objects that JavaScript can work with.

How do I select an HTML element in JavaScript?

Common methods include:

document.getElementById()
document.querySelector()
document.querySelectorAll()

What is querySelector()?

querySelector() returns the first element that matches a CSS selector.

Example:

document.querySelector(".card");

What is querySelectorAll()?

querySelectorAll() returns a NodeList containing all elements that match the selector.

What is the difference between getElementById() and querySelector()?

getElementById() finds an element by ID.

querySelector() accepts CSS selectors and can find IDs, classes, element names, attributes, and more complex selectors.

How do I change text with JavaScript?

Use:

element.textContent = "New text";

What is the difference between textContent and innerHTML?

textContent works with text.

innerHTML reads or writes HTML markup inside an element.

For untrusted text, prefer textContent.

How do I change CSS with JavaScript?

For a single inline style, you can use:

element.style.fontSize = "20px";

For several style changes, adding or removing a CSS class is usually easier to maintain.

How do I add a class with JavaScript?

Use:

element.classList.add("active");

How do I remove a class?

Use:

element.classList.remove("active");

How do I toggle a class?

Use:

element.classList.toggle("active");

How do I check whether a class exists?

Use:

element.classList.contains("active");

How do I change an HTML attribute?

Use:

element.setAttribute("title", "New title");

For many common properties such as href, value, checked, and disabled, DOM properties can be more convenient.

How do I create an HTML element with JavaScript?

Use:

const item = document.createElement("li");

Then add it to the page with something such as:

list.append(item);

How do I remove an HTML element with JavaScript?

Use:

element.remove();

What is classList in JavaScript?

classList provides methods for working with an element’s CSS classes, including add(), remove(), toggle(), contains(), and replace().

What is dataset in JavaScript?

dataset provides access to custom HTML data-* attributes.

For example:

data-product-id="101"

can be read as:

element.dataset.productId

Why does querySelector() return null?

It returns null when no element matches the selector.

Check the selector spelling and make sure the HTML exists before the code runs.

Why does querySelectorAll() not return an array?

It returns a NodeList.

You can still use for...of and forEach() with a static NodeList returned by querySelectorAll() in modern browsers.

Is innerHTML safe?

innerHTML is useful for trusted markup, but inserting untrusted strings into it can create security problems.

Use textContent for plain untrusted text.

Can JavaScript create a complete webpage?

Yes.

JavaScript can create and modify many DOM elements.

However, normal page structure should usually begin with semantic HTML and use JavaScript for dynamic behavior and updates.

What should I learn after DOM manipulation?

Learn JavaScript events next. Events let your DOM code respond to clicks, typing, form submissions, keyboard actions, and other user interactions.

Summary

JavaScript DOM manipulation lets your code work with visible HTML elements.

You learned how to select elements with:

document.getElementById()
document.querySelector()
document.querySelectorAll()

You also learned how to:

  • Read and change text
  • Use textContent
  • Understand innerHTML
  • Add and remove CSS classes
  • Toggle classes
  • Change inline styles
  • Read and change attributes
  • Work with data-* attributes
  • Change form-control properties
  • Create new elements
  • Append and prepend elements
  • Replace elements
  • Remove elements
  • Move through parent and child relationships
  • Use closest()
  • Render arrays and objects into HTML
  • Avoid unsafe innerHTML usage
  • Handle missing elements
  • Reduce unnecessary DOM work

DOM manipulation connects your JavaScript data and logic to the actual webpage.

The next step is learning how to make these changes happen when users interact with the page.

Continue Learning JavaScript

Previous Lesson: JavaScript Objects Explained

Course Home: JavaScript Tutorial for Beginners

Next Lesson: JavaScript Events Explained for Beginners

In the next lesson, you will learn how to respond to clicks, typing, form submissions, keyboard input, and other browser events using addEventListener().

James Parker

James Parker

James Parker is a technology writer and WordPress enthusiast who shares practical guides on SEO, web development, AI tools, and digital growth. He focuses on creating easy-to-follow tutorials that help beginners and professionals build better websites and improve their online presence.