WebDev Story

WebDev Story: HTML DOM

DOM API, node traversal, element relationships

1.0 HTML DOM API

The HTML Document Object Model (DOM) is a tree of nodes representing the structure of a web page. JavaScript interacts with this tree through the DOM API — a set of methods and properties exposed on the global document object and on every element. Only the primary JavaScript thread can access the HTML document. Web Workers may not touch the DOM, which eliminates the need for locking. Table 1 lists the methods and properties most frequently used in JavaScript to respond to user events and modify document content at run-time.

Table 1. — Frequently Used DOM API Methods and Properties

Method / Property Description Example
document.getElementById(id) Returns the element with the given id. let el = document.getElementById("hdr");
document.querySelector(sel) Returns the first element matching a CSS selector. let btn = document.querySelector(".btn");
document.querySelectorAll(sel) Returns all elements matching a CSS selector. let items = document.querySelectorAll("li");
element.addEventListener(type, fn) Attaches an event handler to an element. btn.addEventListener("click", doStuff);
document.createElement(tag) Creates a new element node. let div = document.createElement("div");
parent.appendChild(node) Adds a node to the end of a parent element. div.appendChild(span);
element.remove() Removes the element from the DOM. el.remove();
element.setAttribute(name, val) Sets the value of an attribute. el.setAttribute("class", "active");
element.getAttribute(name) Gets the value of an attribute. let c = el.getAttribute("class");
element.classList.add(name) Adds a CSS class to the element. el.classList.add("highlight");
element.classList.remove(name) Removes a CSS class from the element. el.classList.remove("hidden");
element.innerHTML Gets/sets the HTML markup inside an element. el.innerHTML = "<p>Hi</p>";
element.textContent Gets/sets plain text inside an element. el.textContent = "Hello";

2.0 Node Traversal

Every item in the DOM tree is a Node: elements, text content, comments, and the document itself are all nodes. The Node interface is the base for all of them.
  • Element node: <p>hello</p>
  • Text node: "hello"
  • Comment node: <!-- a comment -->
  • Document node: the root document
Table 2 shows the node properties used to walk the DOM tree.
Table 2. — Node Tree Navigation
Property Description Example
node.parentNode Returns the parent node of the element. let parent = el.parentNode;
node.childNodes Returns all child nodes (including text/comment nodes). let kids = el.childNodes;
node.children Returns only child elements (no text/comment). let elems = el.children;
node.firstChild Returns the first child node. let first = el.firstChild;
node.lastChild Returns the last child node. let last = el.lastChild;
node.firstElementChild Returns the first child element. let fe = el.firstElementChild;
node.lastElementChild Returns the last child element. let le = el.lastElementChild;
node.nextSibling Returns the next sibling node (may be text). let sib = el.nextSibling;
node.previousSibling Returns the previous sibling node (may be text). let prev = el.previousSibling;
node.nextElementSibling Returns the next sibling element. let sibEl = el.nextElementSibling;
node.previousElementSibling Returns the previous sibling element. let prevEl = el.previousElementSibling;

3.0 Document Element Traversal

Elements are the primary unit of HTML page structure. The HTMLElement type extends Node with element-specific methods for selector matching, ancestor searching, and scoped descendant queries.
<div style="position:fixed; top:5rem; left:3rem; background-color: var(--light);">
  element fixed near top-left of page
</div>
Table 3. — DOM Element Relationships
Method Description Example
element.closest(selector) Finds the nearest ancestor (or self) matching a CSS selector. let form = btn.closest("form");
element.matches(selector) Checks if the element matches a CSS selector. if (el.matches(".active")) { … }
node.contains(other) Returns true if the node contains the other node. if (div.contains(span)) { … }
element.hasChildNodes() Returns true if the element has any children. if (el.hasChildNodes()) { … }
element.getRootNode() Returns the root node (document or shadow root). let root = el.getRootNode();
element.querySelectorAll(sel) Scoped search for all matching descendants. let links = nav.querySelectorAll("a");

4.0 References — Full DOM API Overview

The table below groups the DOM API by interface, listing key methods and properties for each, along with a brief description and example.
Table 4. — DOM API by Interface
Interface Key Methods / Properties Description Example
Node appendChild
removeChild
replaceChild
cloneNode
normalize
Core manipulation of nodes: adding, removing, cloning, and normalization. const p = document.createElement('p');
document.body.appendChild(p);
Element getAttribute / setAttribute / removeAttribute / hasAttribute
querySelector / querySelectorAll
closest / matches
Represents element nodes: attribute access, descendant queries, and selector matching. const el = document.querySelector('.item');
if (el.matches('.active')) { … }
HTMLElement focus() / blur() / click()
scrollIntoView()
getBoundingClientRect()
dataset
insertAdjacentHTML
HTML-specific features: focus control, geometry, data-* access, and insertion helpers. el.dataset.id = '42';
el.scrollIntoView();
Document createElement
createTextNode
getElementById
querySelectorAll
body / head / documentElement
Root of the DOM: create nodes, access top-level elements, and perform global queries. const div = document.createElement('div');
document.body.appendChild(div);
EventTarget addEventListener
removeEventListener
dispatchEvent
Event handling: subscribe, unsubscribe, and emit events. el.addEventListener('click', e => console.log(e));
el.dispatchEvent(new Event('custom'));
Tree traversal parentNode / children / childNodes
nextSibling / previousSibling
replaceWith / remove / prepend / append
Navigate and modify the DOM structure, including inserting and replacing elements. el.replaceWith(document.createElement('span'));
Selectors querySelector / querySelectorAll
getElementById
getElementsByClassName
getElementsByTagName
Find elements using CSS selectors or legacy collection methods (some live). const items = document.getElementsByClassName('card');
Attributes vs Properties setAttribute / getAttribute
property access (e.g., el.value)
dataset
Attributes are markup; properties are JS object fields. Reflection patterns sync them. el.setAttribute('data-role', 'admin');
console.log(el.dataset.role);
Events new Event / MouseEvent / CustomEvent
event.preventDefault()
event.stopPropagation()
Creation, dispatch, and handling of events. Supports bubbling, capturing, and delegation. el.addEventListener('submit', e => { e.preventDefault(); });
Shadow DOM attachShadow({mode})
<slot>
Encapsulation of markup/styles; slotting projects light DOM content into shadow DOM. const root = el.attachShadow({mode:'open'});
root.innerHTML = '<slot></slot>';
Custom Elements class X extends HTMLElement
customElements.define(name, ctor)
connectedCallback
attributeChangedCallback
Define new HTML tags with lifecycle hooks and encapsulated behavior. customElements.define('my-widget', MyWidget);
MutationObserver new MutationObserver(cb)
observe(target, options)
Watch DOM changes (child list, attributes, subtree) and react programmatically. const obs = new MutationObserver(m => console.log(m));
obs.observe(el, { childList: true });
Geometry / Layout getBoundingClientRect()
window.getComputedStyle()
Measure element size/position and computed styles, essential for layout logic. const rect = el.getBoundingClientRect();
Class / Data helpers classList (add/toggle/contains/remove)
dataset
Utility accessors for manipulating CSS classes and data-* attributes easily. el.classList.toggle('active');
Templates <template>
template.content.cloneNode(true)
Define inert HTML fragments to instantiate multiple times. const tpl = document.getElementById('tpl');
document.body.appendChild(tpl.content.cloneNode(true));
DocumentFragment createDocumentFragment() Batch DOM insertions efficiently; not rendered until appended. const frag = document.createDocumentFragment();
frag.appendChild(document.createElement('div'));
document.body.appendChild(frag);
CustomEvent new CustomEvent(type, { detail }) Dispatch events with structured payloads. el.dispatchEvent(new CustomEvent('update', { detail: { id: 5 } }));