# Advanced DOM Manipulation – Building Dynamic Interfaces

Yesterday, I learned about **Destructuring, Spread, and Rest Operators** and how they make working with arrays, objects, and function arguments much cleaner.

Today, I went back to one of the most important parts of frontend JavaScript:

**The DOM.**

I focused on how JavaScript can dynamically create, update, remove, and manage HTML elements.

This is important because modern web applications constantly change what users see without reloading the entire page.

Let's dive in.

* * *

# What is the DOM?

**DOM** stands for **Document Object Model**.

When a browser loads an HTML document, it creates a tree-like representation of the page.

For example:

```text
Document
   │
   └── HTML
       ├── HEAD
       └── BODY
           ├── H1
           ├── P
           └── BUTTON
```

JavaScript can interact with this structure to dynamically change the webpage.

* * *

# Selecting Elements

One of the first things we need to do is select elements from the DOM.

### `getElementById()`

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

* * *

### `querySelector()`

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

We can also select classes:

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

* * *

### `querySelectorAll()`

When we need multiple elements:

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

This returns a collection of matching elements.

* * *

# Changing Text

We can change an element's text using:

```javascript
title.textContent = "Hello JavaScript!";
```

For example:

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

JavaScript:

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

title.textContent =
    "New Title";
```

* * *

# Changing HTML

We can also modify the HTML inside an element using:

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

However, `innerHTML` should be used carefully when inserting untrusted user-controlled content because it can introduce security problems such as XSS.

When we only need text, `textContent` is generally safer and clearer.

* * *

# Changing Styles

JavaScript can modify inline styles:

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

title.style.fontSize = "40px";
```

Another example:

```javascript
title.style.marginTop = "20px";
```

However, for larger applications, changing CSS classes is usually cleaner.

* * *

# Working With Classes

We can use `classList` to manage CSS classes.

### Add a class

```javascript
element.classList.add("active");
```

### Remove a class

```javascript
element.classList.remove("active");
```

### Toggle a class

```javascript
element.classList.toggle("active");
```

### Check whether a class exists

```javascript
element.classList.contains("active");
```

This is extremely useful for interactive UI elements.

* * *

# Creating Elements

JavaScript can create completely new HTML elements.

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

Then:

```javascript
paragraph.textContent =
    "Created with JavaScript!";
```

* * *

# Adding Elements to the Page

We can append the element:

```javascript
document.body.append(paragraph);
```

Or append it to a specific container:

```javascript
const container =
    document.querySelector("#container");

container.append(paragraph);
```

* * *

# Creating a Dynamic List

Suppose we have:

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

JavaScript:

```javascript
const skills = [
    "HTML",
    "CSS",
    "JavaScript",
    "React"
];

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

skills.forEach(skill => {

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

    li.textContent = skill;

    list.append(li);

});
```

Now the list is generated dynamically from JavaScript data.

* * *

# Removing Elements

We can remove an element using:

```javascript
element.remove();
```

For example:

```javascript
const paragraph =
    document.querySelector("p");

paragraph.remove();
```

This removes it from the DOM.

* * *

# Creating Attributes

We can set attributes using:

```javascript
element.setAttribute(
    "data-id",
    "123"
);
```

Read an attribute:

```javascript
element.getAttribute("data-id");
```

Check whether it exists:

```javascript
element.hasAttribute("data-id");
```

Remove it:

```javascript
element.removeAttribute("data-id");
```

* * *

# Using `dataset`

For custom `data-*` attributes, JavaScript provides `dataset`.

HTML:

```html
<div
    id="user"
    data-user-id="123"
    data-role="developer">
</div>
```

JavaScript:

```javascript
const user =
    document.querySelector("#user");

console.log(
    user.dataset.userId
);

console.log(
    user.dataset.role
);
```

This is useful for attaching small pieces of metadata to DOM elements.

* * *

# Creating Elements From Data

Now we can combine what we've learned from previous days.

Suppose we have:

```javascript
const users = [
    {
        name: "Saurabh",
        role: "Developer"
    },
    {
        name: "Rahul",
        role: "Designer"
    }
];
```

We can dynamically create user cards:

```javascript
const container =
    document.querySelector("#users");

users.forEach(user => {

    const card =
        document.createElement("div");

    card.classList.add("card");

    const name =
        document.createElement("h2");

    name.textContent = user.name;

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

    role.textContent = user.role;

    card.append(name, role);

    container.append(card);

});
```

This is a fundamental pattern in vanilla JavaScript.

* * *

# Event Listeners on Dynamic Elements

We can also add events to elements we create.

```javascript
const button =
    document.createElement("button");

button.textContent =
    "Click Me";

button.addEventListener(
    "click",
    () => {

        console.log(
            "Button clicked!"
        );

    }
);

document.body.append(button);
```

Now the dynamically created button behaves like any normal HTML element.

* * *

# Event Delegation

When many elements have similar events, **event delegation** can be useful.

Suppose:

```html
<ul id="users">

    <li data-id="1">
        Saurabh
    </li>

    <li data-id="2">
        Rahul
    </li>

</ul>
```

Instead of attaching a separate listener to every `li`, we can listen on the parent:

```javascript
const users =
    document.querySelector("#users");

users.addEventListener(
    "click",
    (event) => {

        const item =
            event.target.closest("li");

        if (!item) return;

        console.log(
            item.dataset.id
        );

    }
);
```

This works because events bubble up through the DOM.

* * *

# `createElement()` vs `innerHTML`

Both can be used to create dynamic content, but they have different characteristics.

### `createElement()`

```javascript
const p =
    document.createElement("p");

p.textContent = "Hello";
```

Advantages:

*   More explicit
    
*   Safer for text content
    
*   Useful for constructing elements programmatically
    

### `innerHTML`

```javascript
container.innerHTML =
    "<p>Hello</p>";
```

Advantages:

*   Convenient for larger HTML snippets
    
*   Can be concise
    

But inserting untrusted strings through `innerHTML` can create security vulnerabilities.

* * *

# DOM + Array Methods

This is where today's lesson connects directly with Day 53.

We can use:

```javascript
users
    .filter(user => user.active)
    .map(user => user.name);
```

and then render the result into the DOM.

This creates a powerful workflow:

```text
Data
 ↓
filter()
 ↓
map()
 ↓
Create DOM Elements
 ↓
Append to Page
```

This is very similar to the data-driven rendering patterns I'll encounter in React.

* * *

# Best Practices

✔ Use `textContent` when inserting plain text.

✔ Prefer CSS classes over excessive inline styles.

✔ Use `classList` to manage UI states.

✔ Use `createElement()` when programmatically constructing DOM elements.

✔ Be careful with `innerHTML` and never insert untrusted content into it without appropriate sanitization.

✔ Use event delegation when managing many similar dynamic elements.

✔ Keep data and rendering logic reasonably separated.

* * *

# My Biggest Takeaway

Today, I learned how JavaScript can dynamically control the webpage.

I can now:

**Select → Create → Modify → Append → Remove → Interact**

I also connected today's DOM concepts with yesterday's functional programming:

**Data → filter/map → DOM → UI**

This is an important bridge toward React because React essentially gives developers a more structured way to describe how UI should be generated from application state.
