Handling DOM changes with plain JavaScript

If you are dealing with pure JavaScript without using any library, you probably want to trigger your custom actions on some element event. This is easily done with addEventListener which is in general supported by all now days browsers.

document.getElementById("myButton").addEventListener("click", function(e){ //Do something });

You would usually do this after document loads and DOM with your element is loaded into the browser window.

document.addEventListener("DOMContentLoaded", function(event) { document.getElementById("myButton").addEventListener("click", function(e){ //Do something }); }

Now problem starts if your DOM changes and your element is not loaded initially on DOM load but on Ajax callback. Let's say your element is loaded on Ajax callback. Attaching event listener in this case has to be done after DOM is updated and you element is on the stage.

So far there is no out of the box DOM event on which you can rely on to attach or re-attach your event handler.

Instead of the there is something called MutationObserver or WebKitMutationObserver depending whether page is loaded inside WebKit based browser or not.

document.addEventListener("DOMContentLoaded", function(event) { var observeDOM = (function () { var MutationObserver = window.MutationObserver || window.WebKitMutationObserver, eventListenerSupported = window.addEventListener; return function (obj, callback) { if (MutationObserver) { // define a new observer var obs = new MutationObserver(function (mutations, observer) { if (mutations[0].addedNodes.length || mutations[0].removedNodes.length) callback(); }); // have the observer observe foo for changes in children obs.observe(obj, { childList: true, subtree: true }); } else if (eventListenerSupported) { obj.addEventListener('DOMNodeInserted', callback, false); obj.addEventListener('DOMNodeRemoved', callback, false); } }; })(); // Observe a specific DOM element: observeDOM(document.getElementById('container'), function () { if (typeof setupEventTracking == "function") { //Setup enet handlers } }); }

With MutationObserver you can observe the whole DOM or a specific element which is maybe even more convenient considering you will not update the whole document but rather only a specific element.

In the example above I set the MutationObserver to monitor div element with id container.

References

Disclaimer

Purpose of the code contained in snippets or available for download in this article is solely for learning and demo purposes. Author will not be held responsible for any failure or damages caused due to any other usage.