Skip to main content

Command Palette

Search for a command to run...

Mastering the DOM: Select, Style, Create & Remove Elements with JavaScript

A practical, example-driven guide to understanding the DOM, manipulating elements, changing styles dynamically, and creating/removing nodes—step by st

Published
4 min read
Mastering the DOM: Select, Style, Create & Remove Elements with JavaScript

TL;DR

  • The DOM is a tree of nodes representing your HTML.

  • You can select nodes with querySelector, modify content with textContent/innerHTML, style them with style/classList, and create/remove nodes with createElement, append, remove.

  • Bonus: before/after demo shows what changes on the page.


1) What is the DOM?

DOM (Document Object Model) = a tree-like representation of your HTML in memory. Every tag becomes a node (element node, text node, etc.). JavaScript can traverse this tree, find nodes, read/change attributes, styles, and even create or delete nodes.

Mental model:

  • document is the root.

  • <html><head> and <body>.

  • Inside <body> you’ll have nested elements (div, p, img, ul > li, etc.).

Why it matters:

  • Any interactive feature (open menus, modals, form validation, dynamic lists) depends on DOM manipulation.

2) Selecting Elements

Common Selectors

<ul id="todo-list">
  <li class="todo">Buy milk</li>
  <li class="todo">Study DOM</li>
</ul>
<button id="add-btn">Add</button>
// Single element
const list = document.getElementById('todo-list');          // by id
const firstTodo = document.querySelector('.todo');           // CSS selector

// Multiple elements (NodeList)
const allTodos = document.querySelectorAll('.todo');         // CSS selector all

// Live HTMLCollection (updates when DOM changes)
const lis = document.getElementsByTagName('li');

// Traversal helpers
firstTodo.parentElement;     // <ul>
list.children;               // HTMLCollection of <li>
list.firstElementChild;      // first <li>
list.lastElementChild;       // last <li>

Tip: Prefer querySelector/querySelectorAll for flexible CSS-style selecting.


3) Reading & Modifying Content

<p id="message">Hello, world!</p>
const msg = document.getElementById('message');

// Read text
console.log(msg.textContent);   // "Hello, world!"

// Change text (safe: no HTML parsing)
msg.textContent = 'Updated via JavaScript';

// Inject HTML (⚠️ avoid with user input)
msg.innerHTML = '<strong>Bold move!</strong>';

Attributes & data-attributes

<img id="avatar" src="/img/guest.png" alt="Guest" data-user-id="42">
const avatar = document.getElementById('avatar');

avatar.getAttribute('src');           // "/img/guest.png"
avatar.setAttribute('alt', 'Profile'); 
avatar.dataset.userId;                // "42"
avatar.dataset.role = 'admin';

4) Changing Styles Dynamically

Inline styles (quick tweaks)

msg.style.color = 'rebeccapurple';
msg.style.backgroundColor = '#f0f0ff';
msg.style.padding = '8px 12px';
/* styles.css */
.highlight { background: #fff3cd; color: #664d03; padding: 8px; border-radius: 6px; }
.hidden    { display: none; }
msg.classList.add('highlight');
msg.classList.toggle('hidden');     // hides/shows
msg.classList.remove('highlight');
msg.classList.contains('hidden');   // boolean

Computed styles (read-only)

const styles = getComputedStyle(msg);
console.log(styles.marginTop, styles.fontSize);

5) Creating & Removing Elements

Creating, appending, inserting

const li = document.createElement('li');
li.className = 'todo';
li.textContent = 'Write a blog on DOM';

const list = document.getElementById('todo-list');
list.append(li);                             // append as last child

// Insert before first item
list.insertBefore(li, list.firstElementChild);

// Add HTML chunks (use carefully)
list.insertAdjacentHTML('beforeend', '<li class="todo">Ship it!</li>');

Replacing & removing

// Replace a node
const newP = document.createElement('p');
newP.textContent = 'This replaced the message.';
msg.replaceWith(newP);

// Remove a node
newP.remove();

// Or via parent
// list.removeChild(list.lastElementChild);

6) Events + DOM Manipulation (Practical Demo)

<input id="todo-input" placeholder="New task..." />
<button id="add-btn">Add</button>
<ul id="todo-list"></ul>
const input = document.getElementById('todo-input');
const addBtn = document.getElementById('add-btn');
const list   = document.getElementById('todo-list');

addBtn.addEventListener('click', () => {
  const text = input.value.trim();
  if (!text) return;

  const li = document.createElement('li');
  li.className = 'todo';
  li.textContent = text;

  // remove on click
  li.addEventListener('click', () => li.remove());

  list.append(li);
  input.value = '';
});

// Enter key adds too
input.addEventListener('keydown', (e) => {
  if (e.key === 'Enter') addBtn.click();
});

What’s happening:

  • You create elements from input.

  • You attach event handlers to new elements.

  • Clicking a task removes it → tiny “to-do” app in ~20 lines.


7) Before & After: Dynamic Page Example

Before (HTML only)

<div class="card">
  <h2 id="title">Welcome</h2>
  <p id="desc">This is a static description.</p>
  <button id="cta">Surprise me</button>
</div>

After (JavaScript applies changes)

const title = document.getElementById('title');
const desc  = document.getElementById('desc');
const cta   = document.getElementById('cta');

cta.addEventListener('click', () => {
  title.textContent = '🎉 DOM Magic!';
  desc.textContent  = 'This text and styles were updated via JavaScript.';
  document.querySelector('.card').classList.add('highlight');

  // Add a confetti note
  const note = document.createElement('p');
  note.textContent = '✨ New element inserted dynamically!';
  note.className = 'highlight';
  cta.insertAdjacentElement('afterend', note);
});

Result: The card’s title and description change, a new paragraph appears, and styles update—classic “before/after” DOM manipulation.


8) Performance & Best Practices

  • Batch DOM writes: frequent layout thrashing is slow. Combine edits: set classes rather than many inline styles, or use a DocumentFragment for many inserts.

  • Event delegation: attach one listener to a parent instead of many children.

      list.addEventListener('click', (e) => {
        if (e.target.matches('.todo')) e.target.remove();
      });
    
  • Avoid innerHTML with untrusted data: prevents XSS. Prefer textContent, or sanitize.

  • Prefer CSS for visual rules: JS toggles classes; CSS defines appearance.


9) Quick Reference (Cheat Sheet)

  • Select: querySelector, querySelectorAll, getElementById

  • Content: textContent, innerHTML

  • Style: element.style.*, classList.add/remove/toggle/contains

  • Create: createElement, append, prepend, insertBefore, insertAdjacentHTML/Element

  • Remove: remove, removeChild

  • Events: addEventListener, event delegation

  • Traversal: parentElement, children, firstElementChild, nextElementSibling