DNA⚡ JavaScriptDOM, BOM & Web APIs
ðŸĢHatchlingJavaScriptDOMBOMWeb APIs

DOM, BOM & Web APIs

The DOM is your application's interface to the rendered page. The BOM gives you browser-level control. Web APIs extend JavaScript beyond the language spec. Together they form the runtime platform.

DOM, BOM & Web APIs

JavaScript the language is tiny. JavaScript the platform — with the DOM, BOM, and hundreds of Web APIs — is vast. Senior engineers understand which APIs the browser provides, how the DOM tree maps to the render tree, and when to use native APIs instead of framework abstractions.

The DOM (Document Object Model)

The DOM is a tree-structured API that represents the HTML document as objects:

document
└── html
    ├── head
    │   ├── title
    │   └── meta
    └── body
        ├── header
        │   └── nav
        ├── main
        │   ├── h1
        │   └── p
        └── footer

DOM Selection Methods

// Modern — preferred
document.querySelector('.card');           // First match
document.querySelectorAll('.card');        // All matches (static NodeList)
element.closest('.parent');               // Nearest ancestor matching selector
 
// Legacy — still fast for simple lookups
document.getElementById('app');           // By ID (fastest)
document.getElementsByClassName('card');  // Live HTMLCollection
document.getElementsByTagName('div');     // Live HTMLCollection

Key distinction: querySelectorAll returns a static NodeList (snapshot). getElementsByClassName returns a live HTMLCollection (updates when DOM changes).

const live = document.getElementsByClassName('item');
const static_ = document.querySelectorAll('.item');
 
document.body.innerHTML += '<div class="item">New</div>';
 
live.length;    // Updated — includes new element
static_.length; // Same as before — snapshot

DOM Manipulation

const div = document.createElement('div');
div.className = 'card';
div.textContent = 'Hello';
div.setAttribute('data-id', '42');
 
parent.appendChild(div);
parent.insertBefore(div, referenceNode);
parent.removeChild(div);
parent.replaceChild(newNode, oldNode);
 
// Modern methods
parent.append(div, 'text', anotherDiv);  // Append multiple nodes/strings
parent.prepend(div);                      // Insert at start
element.before(sibling);                  // Insert before element
element.after(sibling);                   // Insert after element
element.replaceWith(newElement);          // Replace element
element.remove();                         // Remove self

innerHTML vs textContent vs innerText

PropertyReturnsXSS RiskPerformance
innerHTMLHTML stringYes — parses HTMLSlow (triggers parse)
textContentRaw text of all descendantsNoFast
innerTextVisible text (respects CSS)NoSlow (triggers reflow)
// DANGEROUS — XSS if userInput contains <script>
element.innerHTML = userInput;
 
// SAFE — escapes HTML
element.textContent = userInput;

DocumentFragment for Batch DOM Updates

const fragment = document.createDocumentFragment();
 
for (let i = 0; i < 1000; i++) {
  const li = document.createElement('li');
  li.textContent = `Item ${i}`;
  fragment.appendChild(li);
}
 
// Single DOM insertion — one reflow instead of 1000
list.appendChild(fragment);

The BOM (Browser Object Model)

The BOM provides access to browser-level features outside the document:

window

window.innerWidth;          // Viewport width (excluding scrollbar)
window.innerHeight;         // Viewport height
window.outerWidth;          // Browser window width
window.scrollX;             // Horizontal scroll position
window.scrollY;             // Vertical scroll position
window.devicePixelRatio;    // Display density (1 = standard, 2 = retina)
 
window.open(url, '_blank');
window.close();
window.print();
 
window.scrollTo({ top: 0, behavior: 'smooth' });

navigator

navigator.userAgent;           // User agent string (unreliable for detection)
navigator.language;            // Browser language ('en-US')
navigator.onLine;              // Network connectivity
navigator.clipboard;           // Clipboard API
navigator.geolocation;         // Geolocation API
navigator.serviceWorker;       // Service Worker registration
navigator.mediaDevices;        // Camera/microphone access
navigator.share(data);         // Web Share API

location

location.href;       // Full URL
location.origin;     // Protocol + host + port
location.pathname;   // Path (/page/subpage)
location.search;     // Query string (?key=value)
location.hash;       // Fragment (#section)
location.hostname;   // Domain name
 
location.assign(url);    // Navigate (adds to history)
location.replace(url);   // Navigate (replaces current entry)
location.reload();       // Reload page

history

history.pushState(state, '', '/new-url');   // Add entry without navigation
history.replaceState(state, '', '/url');    // Replace current entry
history.back();                             // Go back
history.forward();                          // Go forward
history.go(-2);                             // Go back 2 entries
 
window.addEventListener('popstate', (e) => {
  console.log('Navigation:', e.state);
});

pushState / replaceState is how SPAs implement client-side routing without full page reloads.

Essential Web APIs

Timers

const timeoutId = setTimeout(fn, delay);    // Run once after delay
const intervalId = setInterval(fn, delay);  // Run repeatedly
clearTimeout(timeoutId);
clearInterval(intervalId);
 
// requestAnimationFrame — syncs with display refresh
const rafId = requestAnimationFrame(callback);
cancelAnimationFrame(rafId);

setTimeout(fn, 0) is not immediate — it schedules fn as a macrotask, running after the current call stack clears and all microtasks complete.

requestAnimationFrame

function animate(timestamp) {
  element.style.transform = `translateX(${timestamp / 10}px)`;
  if (timestamp < 2000) {
    requestAnimationFrame(animate);
  }
}
requestAnimationFrame(animate);

Runs at display refresh rate (~60fps). Pauses when tab is hidden. Always prefer over setInterval for visual animations.

Intersection Observer

const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      loadImage(entry.target);
      observer.unobserve(entry.target);
    }
  });
}, { rootMargin: '200px', threshold: 0 });
 
document.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));

MutationObserver

const observer = new MutationObserver((mutations) => {
  mutations.forEach(mutation => {
    if (mutation.type === 'childList') {
      console.log('Children changed:', mutation.addedNodes, mutation.removedNodes);
    }
  });
});
 
observer.observe(element, { childList: true, subtree: true, attributes: true });

ResizeObserver

const observer = new ResizeObserver((entries) => {
  for (const entry of entries) {
    const { width, height } = entry.contentRect;
    console.log(`Resized to ${width}x${height}`);
  }
});
 
observer.observe(element);

Clipboard API

await navigator.clipboard.writeText('Copied text');
const text = await navigator.clipboard.readText();

Geolocation API

navigator.geolocation.getCurrentPosition(
  (position) => {
    const { latitude, longitude } = position.coords;
  },
  (error) => console.error(error.message),
  { enableHighAccuracy: true, timeout: 5000 }
);

Interview Signal

Senior candidates demonstrate:

  1. DOM efficiency — DocumentFragment for batch inserts, textContent over innerHTML, static vs live collections
  2. BOM fluency — history.pushState for SPA routing, navigator API awareness
  3. Modern APIs — IntersectionObserver over scroll events, ResizeObserver over window resize, MutationObserver for DOM watching
  4. Security awareness — innerHTML XSS risks, textContent as the safe alternative
  5. Timer precision — requestAnimationFrame for animation, setTimeout(fn, 0) as macrotask scheduling, timer clamping