Fire a function when innerHTML of element changes?

wirrew picture wirrew · Nov 19, 2017 · Viewed 9k times · Source

I want to fire a function when the innerHTML of a div element changes.

Been testing with element.addEventListener('DOMCharacterDataModified', myFunction()); but it does not seem to work properly. It fires once when the page is loaded but never again after? See example code below.

Anyone have a solution to my task? Any help is greatly appreciated!

The task:

  1. I have an empty div.
  2. At random it will be fed with data from an external source (that I do not have control of).
  3. Everytime when the innerHTML changes, I want to fire myFunction().

My current example code:

var element = document.getElementById('div');

element.addEventListener('DOMCharacterDataModified', myFunction());

function myFunction() {
    console.log(element.innerHTML);
}

setTimeout(function(){
    element.innerHTML = 'Hello World!';
}, 1000);

setTimeout(function(){
    element.innerHTML = 'Hello Space!';
}, 2000);

The setTimeouts visualize the data feeding from an external source.

If possible it needs to be JS only, but jQuery could be used if really needed.


Thanks in advance!

// wirrew

Answer

michaeluskov picture michaeluskov · Nov 19, 2017

Use DOMSubtreeModified event:

var element = document.getElementById('div');

element.addEventListener('DOMSubtreeModified', myFunction);

function myFunction(e) {
    console.log(element.innerHTML);
}

setTimeout(function(){
    element.innerHTML = 'Hello World!';
}, 1000);

setTimeout(function(){
    element.innerHTML = 'Hello Space!';
}, 2000);
<div id="div"></div>

BTW, DOM mutation events were deprecated. Use MutationObserver:

window.addEventListener('load', function () {
  var element = document.getElementById('div');

  var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
  var observer = new MutationObserver(myFunction);
  observer.observe(element, {
	  childList: true
  });

  function myFunction() {
    console.log(element);
    console.log(element.innerHTML);
  }

  setTimeout(function(){
    element.innerHTML = 'Hello World!';
  }, 1000);

  setTimeout(function(){
    element.innerHTML = 'Hello Space!';
  }, 2000);
});
<div id="div">

Raw snippet on GitHub