HomeGuidesJavaScriptJavaScript DOM Manipulation & Events — querySelector, addEventListener
JavaScript

JavaScript DOM and Events: What Interviews Actually Test

DOM manipulation is a front-end interview staple. Here's what gets tested — from selecting elements to event delegation.

Examifyr·2026·5 min read

Selecting elements

Modern JavaScript uses querySelector and querySelectorAll for DOM selection.

// Single element
document.querySelector("#main");           // by ID
document.querySelector(".btn");            // by class
document.querySelector("input[type=text]"); // by attribute

// Multiple elements (returns NodeList)
document.querySelectorAll(".card");

// Older methods (still tested)
document.getElementById("main");
document.getElementsByClassName("btn");    // HTMLCollection
document.getElementsByTagName("p");        // HTMLCollection
Note: querySelectorAll returns a static NodeList. getElementsByClassName returns a live HTMLCollection — it updates when the DOM changes.

Modifying the DOM

Common ways to read and modify element properties.

const el = document.querySelector("#title");

// Content
el.textContent = "Hello";    // plain text (safe)
el.innerHTML = "<b>Hi</b>"; // parses HTML (XSS risk with user input!)

// Attributes
el.setAttribute("class", "active");
el.getAttribute("href");
el.removeAttribute("disabled");

// Styles
el.style.color = "red";
el.classList.add("visible");
el.classList.remove("hidden");
el.classList.toggle("active");
el.classList.contains("active"); // boolean

Creating and inserting elements

createElement builds a new element; various methods insert it.

const li = document.createElement("li");
li.textContent = "New item";
li.classList.add("item");

const ul = document.querySelector("ul");
ul.appendChild(li);                     // append at end
ul.prepend(li);                         // insert at start
ul.insertBefore(li, ul.firstChild);     // insert before

// Modern: insertAdjacentElement
el.insertAdjacentElement("beforeend", li);
// positions: beforebegin, afterbegin, beforeend, afterend

Event listeners and bubbling

Events bubble up from the target through its ancestors. Capturing goes the opposite direction.

const btn = document.querySelector("button");

btn.addEventListener("click", (event) => {
    console.log(event.target);      // element clicked
    console.log(event.currentTarget); // element with listener
    event.stopPropagation();        // stop bubbling
    event.preventDefault();         // stop default action
});

// Remove a listener (must use named function)
const handler = () => console.log("clicked");
btn.addEventListener("click", handler);
btn.removeEventListener("click", handler);

Event delegation

Instead of adding listeners to many child elements, add one listener to the parent and check event.target.

const list = document.querySelector("ul");

// ONE listener on parent handles ALL list items:
list.addEventListener("click", (event) => {
    if (event.target.tagName === "LI") {
        console.log("Clicked:", event.target.textContent);
    }
});

// Works for dynamically added items too — unlike:
// document.querySelectorAll("li").forEach(li => li.addEventListener(...))
// which misses items added after the listener was set up
Note: Event delegation is more efficient and handles dynamically added elements. This is a very common interview question.

Exam tip

Event delegation is the most common DOM interview question. Know that it works because events bubble up — a listener on the parent fires for events on any descendant, including ones added dynamically.

🎯

Think you're ready? Prove it.

Take the free JavaScript readiness test. Get a score, topic breakdown, and your exact weak areas.

Take the free JavaScript test →

Free · No sign-up · Instant results

← Previous
JavaScript ES6+ Features — Destructuring, Spread, Modules & More
Next →
JavaScript Prototypes & Classes — Inheritance, extends & super
← All JavaScript guides