Question presented to candidate: "A third-party analytics script you don't control keeps injecting an ad banner div somewhere inside your page's content area, and you need to detect and remove it the moment it appears. How would you reliably catch that injection?"
What a strong answer should cover:
- 📌 Interview term:
MutationObserver— a real, built-in browser API that lets code.observe(targetNode, options)and receive a real callback whenever the DOM tree under that target genuinely changes — child nodes added/removed, attributes changed, or text content changed, depending on the configured options. - 📌 Interview term: the real, direct answer to the prompt — verified directly via jsdom (which, unlike
ResizeObserver/IntersectionObserver, genuinely DOES implementMutationObserver): observing a target with{ childList: true, subtree: true }genuinely detected a real, dynamically-injected<script>node appended anywhere under the target, reporting it in a realmutationsarray withtype: "childList"and the injected node present inaddedNodes. - 📌 Interview term: the real, asynchronous, batched callback timing — a precise answer names that
MutationObservercallbacks genuinely fire ASYNCHRONOUSLY, batched as a real MICROTASK — verified directly, a mutation made synchronously did not appear in the log until AFTER the current synchronous script finished and a microtask was allowed to flush — several rapid mutations made in the same tick genuinely arrive together in ONE callback invocation, not one callback per mutation. - 📌 Interview term:
{ childList, subtree, attributes }options — a precise answer names thatMutationObservergenuinely observes NOTHING by default — at least one ofchildList/attributes/characterDatamust be explicitly set totrue, andsubtree: trueis genuinely required to catch a mutation happening on a DESCENDANT of the target, not just the target itself. - A precise answer names the real, practical response pattern for the prompt's own scenario: inside the callback, check each mutation's
addedNodesfor a match (by tag name, class, or a known selector) and call.remove()on it immediately — plus the real caveat that.disconnect()should eventually be called if the watch is no longer needed, to avoid an unnecessary real, ongoing observation cost.
Clarifying questions expected:
- None — this is a definitional/practical question; directly demonstrating the real, verified detection of an injected node is the strong signal.
Code / implementation expected: Yes — a real, jsdom-verified MutationObserver detecting a dynamically injected node and an attribute change, plus proof of .disconnect() stopping further detection.