JavaScript 3 min read

The DOM Explained: How JavaScript Changes a Web Page

The Document Object Model is how JavaScript sees and changes your page. Learn selecting elements, changing content and styles, handling events and avoiding the performance traps of DOM manipulation.

On this page

Key takeaways

  • The DOM (Document Object Model) is the browser’s live, tree-shaped representation of a page that JavaScript can read and change.
  • Common tasks: select elements, listen to events, update text and classes, and create elements.
  • Efficient DOM code matters for responsiveness — batch changes and avoid layout thrashing.

Every interactive feature on this website — the dark-mode toggle, the quick search dropdown, the SEO Library filter, the chatbot — is JavaScript changing the DOM. Understanding the DOM is the key step from “copying snippets” to actually building interfaces.

From HTML to DOM#

When the browser parses HTML, it builds a tree of nodes: document → html → head/body → elements → text. JavaScript works with that tree. If a script changes it, the page updates — but the original HTML source doesn’t.

Selecting elements#

const header  = document.querySelector('.site-header');      // first match
const buttons = document.querySelectorAll('[data-share]');   // all matches (NodeList)
const form    = document.getElementById('contact-form');
const card    = button.closest('.card');                      // nearest ancestor

Responding to events#

const toggle = document.querySelector('[data-theme-toggle]');
toggle.addEventListener('click', () => {
  const root = document.documentElement;
  const next = root.dataset.theme === 'dark' ? 'light' : 'dark';
  root.dataset.theme = next;
});

Event delegation — one listener on a parent handling many children — is efficient and works for elements added later:

document.addEventListener('click', (e) => {
  const btn = e.target.closest('[data-copy-link]');
  if (!btn) return;
  navigator.clipboard.writeText(location.href);
});

Changing content and styles#

Task Code
Change text safely el.textContent = 'Saved!'
Toggle a class el.classList.toggle('is-open')
Set an attribute btn.setAttribute('aria-expanded', 'true')
Show / hide panel.hidden = false
Data attributes el.dataset.state = 'loading' → data-state="loading"
Create and add const li = document.createElement('li'); list.append(li);
Remove el.remove()
Security: innerHTML Never insert user input with innerHTML — it can execute injected scripts (XSS). Use textContent, or escape HTML before inserting. The chatbot on this site escapes every message before rendering it.

Need a hand with this?

Get a quick, honest review of your website’s SEO.

Chat on WhatsApp

Performance: avoid layout thrashing#

Reading layout values (offsetHeight, getBoundingClientRect()) after writing styles forces the browser to recalculate layout. Doing this in a loop causes “layout thrashing” and janky scrolling.

  • Batch reads first, then writes.
  • Use requestAnimationFrame for visual updates on scroll.
  • Use passive scroll listeners: addEventListener('scroll', fn, { passive: true }).
  • Prefer IntersectionObserver over scroll handlers to detect visibility (lazy loading, active TOC links).
  • Keep the DOM reasonably small — very large DOMs slow every interaction (INP).

Accessibility while changing the DOM#

  • Update ARIA states (aria-expanded, aria-pressed) when toggling UI.
  • Move focus into opened dialogs and back to the trigger when closed.
  • Announce dynamic messages with aria-live regions (toasts, chat replies, form status).

SEO note#

Content created only by DOM manipulation after load depends on Google rendering your JavaScript. Keep important content in the server HTML and use JavaScript for enhancement — see JavaScript SEO.

DOM FAQ#

Do I still need jQuery?#

No. Modern browser APIs (querySelector, classList, fetch) cover what jQuery used to simplify.

What’s the virtual DOM?#

Frameworks like React keep an in-memory representation and update the real DOM efficiently. It’s an abstraction over the same DOM.

Why doesn’t my script find the element?#

The script probably runs before the element exists. Load it with defer or wait for DOMContentLoaded.

Found this useful? Share it

Join the discussion

Your email address will not be published. Required fields are marked *

Security code image. If you cannot read it, press refresh or contact me on WhatsApp.