Listening for DOM events

December 2nd, 2016 by Alex Leave a reply »

Lately, there haven’t been a nice way to track DOM changes, like a listener for a class change, or when the actual content of the item changes. There were some trial APIs in DOM3 Events specification called Mutation events, which basically allowed binding events to any element based on your needs (could be DOMNodeInserted or DOMAttrModified or others).

But now, there’s a better way. Behold, the MutationObserver

What is it

MutationObserver is a special class for creating DOM mutation observers (who would’ve thought..). To use it, we need to instantiate a new observer, and then run the observe method. Here is a full working example.

MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
function process() {
	// do something here
var tick = null;
var observer = new MutationObserver(function(mutations, observer) {
	// fired when a mutation occurs
	tick = setTimeout(process, 100);
observer.observe(document.body, {
	childList: true,
	subtree: true

As you might see, we first check if there is a stable API or WebKitMutationObserver, then initialize the actual observer and run its observe method passing the DOM node to listen on, and the actual conditions for observing. There are several different combinations you could use. For example, to listen to a class attribute change on a single node, you can do:

observer.observe(document.getElementById('someelement', {
	attributes: true,
	attributeFilter: ['class']

There is a debate where you should fire the event instantly, or apply some setTimeout, because you don’t want to trash your CPU in case the DOM changes too fast during the small amount of time. That’s why we have a simple trick with setTimeout(process, 100); which delays any action by 100ms, but still makes sure it runs only once.

When and why to use

MutationObserver can be used in environment where you don’t have much control over the generated DOM, but still want to post-process it. External domain script, a Chrome Extension, plugins for compiled and/or obscured scripts are to name a few.

Leave a Reply