πŸŽ“ Velnov

🟨 JavaScript · Topic 16 of 20

DOM Manipulation β€” JavaScript Questions with Answers

30 practice questions on DOM Manipulation, each with the correct answer and a clear explanation of why it is right. Read through them as revision notes, or take this topic as an interactive quiz to test yourself.

2 easy Β· 21 medium Β· 7 hard Β· Part of JavaScript: The language of the web - basics to advanced, 20 topics.

Key concepts in this topic

DOMdocumentquerySelectorSelectorsnullError handlinggetElementByIdNodeListLive collectionstextContentinnerTextXSSSecurityFormsvalueclassListCSStogglestylecreateElementappendChildappendremoveDOM manipulation

Jump to: Easy Β· Medium Β· Hard

Easy questions (2)

Q1. easy

What is the DOM?

  1. A A tree of objects representing the HTML page, which JavaScript can read and change
  2. B A JavaScript library
  3. C A CSS feature
  4. D A type of database

Answer: A β€” A tree of objects representing the HTML page, which JavaScript can read and change

Document Object Model: the browser parses your HTML into a live object tree. Changing the DOM instantly changes what the user sees.

DOMdocument

Q2. easy

Which method selects the FIRST element matching a CSS selector?

document.querySelector("#title");
document.querySelector(".card .btn");
document.querySelectorAll("li");
  1. A document.querySelector(".box")
  2. B document.getElement(".box")
  3. C document.find(".box")
  4. D document.select(".box")

Answer: A β€” document.querySelector(".box")

querySelector accepts any CSS selector and returns the first match (or null). querySelectorAll returns all matches as a NodeList.

querySelectorSelectors

Medium questions (21)

Q3. medium

What does querySelector return when nothing matches?

const el = document.querySelector(".missing");
if (el) el.textContent = "hi";
el?.classList.add("on");
  1. A null
  2. B undefined
  3. C An empty array
  4. D An error

Answer: A β€” null

It returns null, so accessing a property on it throws 'Cannot read properties of null' - the most common DOM error. Check first or use optional chaining.

nullError handling

Q4. medium

What is the difference between getElementById and querySelector?

  1. A getElementById takes a bare id (no #) and is slightly faster; querySelector takes any CSS selector
  2. B They are identical
  3. C querySelector only works on classes
  4. D getElementById returns an array

Answer: A β€” getElementById takes a bare id (no #) and is slightly faster; querySelector takes any CSS selector

getElementById("title") vs querySelector("#title"). The speed difference is negligible in practice; querySelector's flexibility usually wins.

getElementByIdquerySelector

Q6. medium

How do you change the visible TEXT of an element safely?

  1. A el.textContent = "Hello"
  2. B el.value = "Hello"
  3. C el.text = "Hello"
  4. D el.write("Hello")

Answer: A β€” el.textContent = "Hello"

textContent sets plain text and escapes any HTML - safe against injection. innerText is similar but slower (it respects CSS visibility).

textContentinnerText

Q8. medium

How do you read what a user typed into an <input>?

const n = Number(document.querySelector("#age").value);
  1. A input.value
  2. B input.textContent
  3. C input.innerHTML
  4. D input.text

Answer: A β€” input.value

Form controls store their current data in .value (always a STRING - convert with Number() for maths). textContent would be empty for inputs.

Formsvalue

Q9. medium

How do you add a CSS class to an element?

el.classList.add("active");
el.classList.remove("hidden");
el.classList.toggle("open");
el.classList.contains("active");   // true/false
  1. A el.classList.add("active")
  2. B el.class += "active"
  3. C el.addClass("active")
  4. D el.style.class = "active"

Answer: A β€” el.classList.add("active")

classList provides add, remove, toggle and contains - far safer than overwriting className, which would wipe existing classes.

classListCSS

Q10. medium

What does classList.toggle("open") do?

  1. A Adds the class if absent, removes it if present - and returns true/false
  2. B Always adds it
  3. C Always removes it
  4. D Renames the class

Answer: A β€” Adds the class if absent, removes it if present - and returns true/false

Perfect for menus, modals and dark mode. An optional second argument forces the state: toggle("open", isOpen).

classListtoggle

Q11. medium

How do you change an inline style?

el.style.backgroundColor = "red";
el.style.fontSize = "20px";
  1. A el.style.backgroundColor = "red" (camelCase property names)
  2. B el.style.background-color = "red"
  3. C el.css("background-color", "red")
  4. D el.setStyle("background", "red")

Answer: A β€” el.style.backgroundColor = "red" (camelCase property names)

CSS hyphenated names become camelCase in JavaScript because background-color would be parsed as subtraction. Prefer toggling classes over many inline styles.

styleCSS

Q12. medium

How do you create a new element and add it to the page?

const li = document.createElement("li");
li.textContent = "New item";
document.querySelector("ul").appendChild(li);
  1. A const li = document.createElement("li"); parent.appendChild(li);
  2. B document.newElement("li")
  3. C parent.add("<li>")
  4. D document.write("<li>")

Answer: A β€” const li = document.createElement("li"); parent.appendChild(li);

createElement builds a detached element; it appears only once inserted with appendChild, append, prepend or insertBefore.

createElementappendChild

Q13. medium

What is the difference between append() and appendChild()?

  1. A append() accepts multiple nodes AND plain strings; appendChild() takes exactly one node and returns it
  2. B They are identical
  3. C appendChild is newer
  4. D append only works on text

Answer: A β€” append() accepts multiple nodes AND plain strings; appendChild() takes exactly one node and returns it

append is the modern, more flexible method: parent.append(el, "text", el2). appendChild remains widely used and returns the appended node.

appendappendChild

Q14. medium

How do you REMOVE an element from the page?

  1. A el.remove()
  2. B el.delete()
  3. C document.remove(el)
  4. D el.destroy()

Answer: A β€” el.remove()

The modern one-liner. The older equivalent was el.parentNode.removeChild(el).

removeDOM manipulation

Q15. medium

How do you read a data attribute? <div data-user-id="42">

const id = Number(el.dataset.userId);   // 42
  1. A el.dataset.userId
  2. B el.data("user-id")
  3. C el.userId
  4. D el.attributes.userId

Answer: A β€” el.dataset.userId

dataset exposes all data-* attributes, converting kebab-case to camelCase. Values are always strings.

datasetAttributes

Q16. medium

What is the difference between setAttribute and setting a property?

  1. A setAttribute changes the HTML attribute; properties reflect the CURRENT state (they can diverge, e.g. input.value)
  2. B They are identical
  3. C setAttribute is deprecated
  4. D Properties do not exist

Answer: A β€” setAttribute changes the HTML attribute; properties reflect the CURRENT state (they can diverge, e.g. input.value)

After a user types, input.value shows the typed text while getAttribute("value") still shows the original HTML default. Use properties for live state.

Attributes vs properties

Q18. medium

What does el.closest(".card") do?

btn.closest(".card").remove();
  1. A Walks UP the tree from el and returns the nearest ancestor (or el itself) matching the selector
  2. B Finds the nearest child
  3. C Returns the sibling
  4. D Measures distance in pixels

Answer: A β€” Walks UP the tree from el and returns the nearest ancestor (or el itself) matching the selector

closest is invaluable in event delegation: from a clicked button you can find the containing card or row.

closestTraversal

Q19. medium

Which property gives an element's PARENT?

  1. A el.parentElement
  2. B el.parent
  3. C el.up
  4. D el.container

Answer: A β€” el.parentElement

Traversal properties: parentElement, children, firstElementChild, nextElementSibling. (The older node-based versions like childNodes also include text nodes.)

TraversalparentElement

Q21. medium

What does the DOMContentLoaded event mean?

  1. A The HTML is parsed and the DOM is ready - images may still be loading
  2. B Everything including images has loaded
  3. C The page is closing
  4. D CSS finished

Answer: A β€” The HTML is parsed and the DOM is ready - images may still be loading

DOMContentLoaded fires early (ideal for setup); the window 'load' event waits for all images and stylesheets, so it fires much later.

DOMContentLoadedload

Q22. medium

How do you loop over the result of querySelectorAll?

document.querySelectorAll(".item").forEach(el => el.classList.add("on"));
const texts = [...document.querySelectorAll("li")].map(li => li.textContent);
  1. A forEach or for...of - NodeLists support both
  2. B Only a classic for loop
  3. C map() directly
  4. D You cannot loop it

Answer: A β€” forEach or for...of - NodeLists support both

NodeList has forEach and is iterable. It does NOT have map/filter - convert with Array.from(list) or [...list] first.

NodeListArray.from

Q23. medium

What does insertAdjacentHTML("beforeend", html) do?

  1. A Inserts HTML at a precise position without destroying existing children/listeners
  2. B Replaces all content
  3. C Deletes the element
  4. D Only works with text

Answer: A β€” Inserts HTML at a precise position without destroying existing children/listeners

Unlike innerHTML += (which re-parses everything and kills existing event listeners), this inserts efficiently. Positions: beforebegin, afterbegin, beforeend, afterend.

insertAdjacentHTMLPerformance

Q25. medium

How do you check whether an element has a class?

  1. A el.classList.contains("active")
  2. B el.hasClass("active")
  3. C el.class === "active"
  4. D el.classList === "active"

Answer: A β€” el.classList.contains("active")

contains returns a boolean. Comparing className directly fails whenever an element has multiple classes.

classList

Q27. medium

How do you hide an element with JavaScript?

  1. A Toggle a CSS class, or set el.style.display = "none"
  2. B el.hide()
  3. C el.visible = false
  4. D delete el

Answer: A β€” Toggle a CSS class, or set el.style.display = "none"

Adding a class like .hidden { display: none } keeps styling in CSS where it belongs and is easy to animate or override.

styleclassList

Q29. medium

Which is generally better: building HTML strings or creating elements?

  1. A Strings are concise for static markup; createElement is safer with dynamic user data
  2. B Strings are always better
  3. C createElement is always better
  4. D They are identical

Answer: A β€” Strings are concise for static markup; createElement is safer with dynamic user data

Template literals are readable for trusted content, but inserting user data via innerHTML risks XSS. createElement + textContent escapes automatically.

SecurityBest practices

Q30. medium

How do you clear all children of an element?

  1. A el.replaceChildren() (or el.innerHTML = "")
  2. B el.clear()
  3. C el.empty()
  4. D delete el.children

Answer: A β€” el.replaceChildren() (or el.innerHTML = "")

replaceChildren() with no arguments removes everything cleanly and is the modern approach; innerHTML = "" also works and is widely used.

replaceChildreninnerHTML

Hard questions (7)

Q5. hard

What is the difference between an HTMLCollection (getElementsByClassName) and a NodeList (querySelectorAll)?

  1. A HTMLCollection is LIVE (updates automatically); querySelectorAll's NodeList is a static snapshot
  2. B They are the same
  3. C NodeList is live
  4. D HTMLCollection is an array

Answer: A β€” HTMLCollection is LIVE (updates automatically); querySelectorAll's NodeList is a static snapshot

A live collection reflects later DOM changes, which can cause surprising loop behaviour. Static NodeLists are predictable and support forEach.

NodeListLive collections

Q7. hard

Why is innerHTML risky with user-supplied data?

el.textContent = userInput;   // safe
el.innerHTML = userInput;      // dangerous!
  1. A It parses the string as HTML, allowing script/event injection (XSS)
  2. B It is slower only
  3. C It does not work in modern browsers
  4. D It is not risky

Answer: A β€” It parses the string as HTML, allowing script/event injection (XSS)

Inserting untrusted input via innerHTML lets attackers run code in your users' browsers. Use textContent for text; sanitise if HTML is genuinely required.

XSSSecurity

Q17. hard

Why should you avoid updating the DOM inside a long loop?

const frag = document.createDocumentFragment();
items.forEach(t => { const li = document.createElement("li"); li.textContent = t; frag.append(li); });
list.append(frag);   // one DOM update
  1. A Each change can force reflow/repaint - build the content first, then insert once
  2. B Loops cannot touch the DOM
  3. C It causes syntax errors
  4. D There is no problem

Answer: A β€” Each change can force reflow/repaint - build the content first, then insert once

A thousand appendChild calls means a thousand layout recalculations. Build an HTML string or a DocumentFragment and insert it in one operation.

PerformanceDocumentFragment

Q20. hard

Why does this return null? <script src="app.js"></script> is in <head>, and app.js runs document.querySelector("#btn")

<script src="app.js" defer></script>
// or
document.addEventListener("DOMContentLoaded", init);
  1. A The script runs BEFORE the body elements are parsed, so #btn does not exist yet
  2. B querySelector is broken
  3. C The id is wrong
  4. D Scripts cannot use querySelector

Answer: A β€” The script runs BEFORE the body elements are parsed, so #btn does not exist yet

Fix by adding defer to the script tag, moving it before </body>, or wrapping the code in a DOMContentLoaded listener.

deferDOMContentLoaded

Q24. hard

What is wrong with el.innerHTML += "<li>x</li>" in a loop?

  1. A It re-parses ALL the HTML each time and destroys existing elements' event listeners
  2. B It is a syntax error
  3. C It only adds text
  4. D Nothing is wrong

Answer: A β€” It re-parses ALL the HTML each time and destroys existing elements' event listeners

The += reads, concatenates and re-writes the entire subtree, which is slow and replaces existing nodes with new ones (losing listeners and input state).

innerHTMLPerformance

Q26. hard

What does document.querySelector("#list").children give you?

  1. A An HTMLCollection of ELEMENT children only (ignoring text/whitespace nodes)
  2. B All descendants
  3. C Text nodes too
  4. D An array

Answer: A β€” An HTMLCollection of ELEMENT children only (ignoring text/whitespace nodes)

children skips text nodes, unlike childNodes which includes the whitespace between tags - a classic source of unexpected counts.

childrenchildNodes

Q28. hard

What is the difference between offsetWidth and getBoundingClientRect().width?

  1. A offsetWidth is a rounded integer; getBoundingClientRect gives precise fractional values including transforms
  2. B They are identical
  3. C offsetWidth includes margins
  4. D getBoundingClientRect only works on images

Answer: A β€” offsetWidth is a rounded integer; getBoundingClientRect gives precise fractional values including transforms

Use getBoundingClientRect for precise measurement and viewport position (it also returns top/left/right/bottom).

MeasurementsLayout

Practice β€œDOM Manipulation” as a quiz