D

DOM (Document Object Model)

A programming interface that represents HTML and XML documents as a tree structure, allowing JavaScript to interact with and modify page content

The Document Object Model (DOM) is a programming interface for web documents. It represents the structure of HTML and XML documents as a tree of objects, where each node represents part of the document (elements, attributes, text). JavaScript can interact with this tree to dynamically change content, structure, and styling.

How the DOM Works

When a browser loads a web page:

  1. Parses HTML into a tree structure
  2. Creates DOM nodes for each element
  3. Builds the DOM tree with parent-child relationships
  4. Provides API for JavaScript interaction
<!-- HTML -->
<div id="container">
  <h1>Title</h1>
  <p>Content</p>
</div>

Becomes this DOM tree:

document
  └── html
      └── body
          └── div#container
              ├── h1
              │   └── "Title" (text node)
              └── p
                  └── "Content" (text node)

DOM Nodes

Node Types

  • Element nodes - HTML tags (<div>, <p>, <button>)
  • Text nodes - Text content inside elements
  • Attribute nodes - Element attributes (id, class, href)
  • Comment nodes - HTML comments
  • Document node - Root of the DOM tree

Node Relationships

// Parent/Child relationships
element.parentNode        // Parent element
element.childNodes        // All child nodes
element.firstChild        // First child node
element.lastChild         // Last child node

// Sibling relationships
element.previousSibling   // Previous node
element.nextSibling      // Next node

// Element-only relationships (skip text nodes)
element.children          // Element children only
element.firstElementChild // First element child
element.nextElementSibling // Next element sibling

DOM Manipulation

Selecting Elements

// Single element selectors
document.getElementById('header')          // By ID
document.querySelector('.class')          // CSS selector (first match)
document.querySelector('[data-id="123"]') // Attribute selector

// Multiple element selectors
document.getElementsByClassName('item')    // By class (live collection)
document.getElementsByTagName('div')      // By tag (live collection)
document.querySelectorAll('.item')        // CSS selector (static NodeList)

Creating Elements

// Create new elements
const div = document.createElement('div');
const text = document.createTextNode('Hello');

// Set attributes and content
div.className = 'container';
div.id = 'main';
div.textContent = 'Hello World';
div.innerHTML = '<span>HTML content</span>';

// Add to DOM
document.body.appendChild(div);
parentElement.insertBefore(div, referenceNode);

Modifying Elements

// Content
element.textContent = 'Plain text';        // Text only
element.innerHTML = '<b>HTML</b>';         // HTML content (avoid with untrusted input to prevent XSS)

// Attributes
element.setAttribute('data-id', '123');
element.getAttribute('data-id');
element.removeAttribute('data-id');
element.id = 'newId';
element.className = 'class1 class2';

// Styles
element.style.color = 'red';
element.style.display = 'none';
element.classList.add('active');
element.classList.remove('active');
element.classList.toggle('active');

Removing Elements

// Remove from DOM
element.remove();                   // Modern way
parent.removeChild(child);         // Legacy way
element.innerHTML = '';            // Clear content

DOM Events

The DOM provides an event system for handling user interactions:

// Adding event listeners
element.addEventListener('click', handleClick);
element.addEventListener('submit', (e) => {
  e.preventDefault();
  // Handle form submission
});

// For scroll/touch events, consider passive listeners:
// window.addEventListener('scroll', onScroll, { passive: true });

// Event delegation
document.addEventListener('click', (e) => {
  if (e.target.matches('.button')) {
    // Handle button click
  }
});

// Removing event listeners
element.removeEventListener('click', handleClick);

DOM Performance

Reflow and Repaint

DOM changes can trigger:

  • Reflow: Recalculating element positions and geometry
  • Repaint: Updating visual appearance

Performance Tips

// Bad: Multiple DOM updates
for (let i = 0; i < 1000; i++) {
  document.body.innerHTML += '<div>' + i + '</div>';
}

// Good: Batch updates
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
  const div = document.createElement('div');
  div.textContent = i;
  fragment.appendChild(div);
}
document.body.appendChild(fragment);

// Good: Use CSS classes instead of inline styles
element.classList.add('hidden');  // Better
element.style.display = 'none';   // Causes reflow

Virtual DOM

Some frameworks use a Virtual DOM - a JavaScript representation of the real DOM:

  • React, Vue: Compare virtual DOM trees and update only changes
  • Benefits: Batched updates, predictable performance
  • Trade-off: Memory overhead, additional complexity

DOM vs HTML

HTMLDOM
Static markup languageDynamic object model
Text-based source codeIn-memory tree structure
What you writeWhat the browser creates
Cannot be manipulatedCan be manipulated via JavaScript

Common DOM Methods

Traversal

// Find elements
element.closest('.parent')           // Nearest parent matching selector
element.contains(otherElement)       // Check if contains element
element.matches('.selector')          // Check if matches selector

Dimensions & Position

// Size
element.offsetWidth / offsetHeight   // Including borders
element.clientWidth / clientHeight   // Including padding
element.scrollWidth / scrollHeight   // Including overflow

// Position
element.offsetTop / offsetLeft       // Position relative to offsetParent
element.getBoundingClientRect()      // Position relative to viewport

Browser Compatibility

Modern DOM APIs with good support:

  • querySelector/querySelectorAll - All modern browsers
  • classList - All modern browsers
  • Element.remove() - All modern browsers
  • Element.closest() - All modern browsers

Legacy alternatives still needed for:

  • Very old browsers (IE11 and below)
  • Some mobile browsers

Common Pitfalls

Live vs Static Collections

// Live collection (updates automatically)
const divs = document.getElementsByTagName('div');
console.log(divs.length); // 5
document.body.appendChild(document.createElement('div'));
console.log(divs.length); // 6

// Static collection (snapshot)
const divs2 = document.querySelectorAll('div');
console.log(divs2.length); // 5
document.body.appendChild(document.createElement('div'));
console.log(divs2.length); // Still 5

Memory Leaks

// Potential leak: event listener holds reference
element.addEventListener('click', () => {
  // This closure keeps element in memory
});

// Clean up when removing elements
element.removeEventListener('click', handler);
element.remove();
  • Screen Reader - Interprets DOM for accessibility
  • Live Regions - DOM areas that announce changes
  • Shadow DOM - Encapsulated DOM trees
  • CSSOM - CSS Object Model

Key Takeaways

  • The DOM is a tree representation of HTML documents
  • JavaScript manipulates web pages through the DOM API
  • DOM operations can be expensive - batch updates when possible
  • Understanding DOM relationships helps write better selectors
  • Modern frameworks abstract DOM manipulation but understanding it is still crucial