JavaScript DOM Manipulation 2 — Questions and Answers
Question 1: What does `document.querySelector()` return?
- An array of all matching elements
- The first element matching the CSS selector (Correct answer)
- A NodeList of all matching elements
- A boolean indicating whether the element exists
Correct answer: The first element matching the CSS selector
`document.querySelector()` returns the first Element within the document that matches the provided CSS selector string, or `null` if no match is found.
`querySelector()` accepts any valid CSS selector. It traverses the DOM in depth-first, pre-order traversal and returns the first matching element. Unlike `getElementById()`, it can match any CSS selector. `querySelectorAll()` returns a static NodeList of all matches. Both methods can be called on any element, not just `document`.
Question 2: What is event bubbling in the DOM?
- Events that occur repeatedly at intervals
- An event that propagates from the target element up through its ancestors (Correct answer)
- When multiple events fire at the same time
- An event triggered by browser animations
Correct answer: An event that propagates from the target element up through its ancestors
Event bubbling is the process where an event triggered on a child element propagates upward through the DOM tree, triggering any registered event listeners on ancestor elements.
When you click a button inside a div, the click event fires on the button first (target phase), then bubbles up to the div, the body, the html element, and finally the document/window. You can stop this with `event.stopPropagation()`. Event delegation (attaching one listener to a parent) takes advantage of this behavior for efficiency.
Question 3: How do you add a CSS class to a DOM element?
- element.style.class = 'myClass'
- element.className = 'myClass'
- element.classList.add('myClass') (Correct answer)
- element.addStyle('myClass')
Correct answer: element.classList.add('myClass')
`element.classList.add('myClass')` is the modern and recommended way to add a CSS class. It preserves existing classes, unlike `element.className = 'myClass'` which replaces all classes.
`classList` is a `DOMTokenList` providing methods: `add()`, `remove()`, `toggle()`, `contains()`, and `replace()`. Using `element.className = 'myClass'` replaces all existing classes. `element.style.class` is invalid. The `classList` API is preferred because it can add multiple classes at once (`classList.add('a', 'b')`) and is easier to work with programmatically.
Question 4: What does `event.preventDefault()` do?
- Stops the event from bubbling up the DOM
- Prevents the browser's default action for the event (Correct answer)
- Removes all event listeners from the element
- Cancels the event object
Correct answer: Prevents the browser's default action for the event
`event.preventDefault()` tells the browser not to execute its default behavior for the event. For example, preventing a form from submitting, stopping a link from navigating, or blocking a checkbox from toggling.
Common uses: prevent form submission (`form.addEventListener('submit', e => e.preventDefault())`), prevent anchor navigation, prevent context menu on right-click, prevent drag-and-drop default behaviors. Note that `preventDefault()` does NOT stop event bubbling — for that, use `stopPropagation()`. Some events are not cancelable (`Event.cancelable === false`).
Question 5: What is the difference between `innerHTML` and `textContent`?
- They are identical
- `innerHTML` parses HTML tags; `textContent` treats content as plain text (Correct answer)
- `textContent` parses HTML; `innerHTML` is for plain text
- `innerHTML` is deprecated
Correct answer: `innerHTML` parses HTML tags; `textContent` treats content as plain text
`innerHTML` sets or gets the HTML markup inside an element, parsing HTML tags. `textContent` sets or gets the text content, treating everything as plain text (HTML tags are escaped, not rendered).
Setting `innerHTML` with user-provided content is an XSS (Cross-Site Scripting) vulnerability risk since embedded scripts and event handlers can execute. `textContent` is safe because it doesn't parse HTML. `innerText` is similar to `textContent` but is aware of CSS styling (e.g., it excludes text in `display:none` elements) and triggers reflow.
Question 6: How do you create a new HTML element and add it to the DOM?
- document.newElement('div'); document.body.addChild(el)
- const el = document.createElement('div'); document.body.appendChild(el) (Correct answer)
- document.body.html += '<div>'
- new HTMLElement('div').attach(document.body)
Correct answer: const el = document.createElement('div'); document.body.appendChild(el)
`document.createElement('tagName')` creates a new element node. `parent.appendChild(element)` appends it as the last child of the parent element.
The DOM manipulation API: `createElement` creates the element (not yet in the document), then `appendChild()` inserts it. Other insertion methods include `insertBefore()`, `prepend()`, `append()` (which can also accept strings), `insertAdjacentElement()`, and the newer `before()`/`after()` methods. `document.body.html +=` is extremely inefficient as it re-parses the entire body.
What does `document.querySelector()` return?