MutationObserver watches a DOM node and fires a callback with a
batch of MutationRecords whenever it changes —
no polling required. Toggle the observer config below, poke the sandbox,
and watch the records roll in.
The classic use case: a chat widget, ad slot, or analytics script injects markup
after your code runs. Instead of a setInterval poll,
observe and react the moment it lands:
// polling: wasteful, races with the widget const timer = setInterval(() => { const el = document.querySelector('#chat-widget'); if (el) { clearInterval(timer); initWidget(el); } }, 250); // observer: exact, zero wasted work const obs = new MutationObserver((records) => { for (const m of records) { for (const n of m.addedNodes) { if (n.id === 'chat-widget') { obs.disconnect(); initWidget(n); } } } }); obs.observe(document.body, { childList: true, subtree: true });
One caution: subtree: true on a huge root like
document.body watches everything. Always observe the
narrowest node that contains what you care about.