15

I recently came across this awesome MutationObserver feature which sort of keep tracks of the changes on any dom element. I used the code that was shown on the mozilla developer network, but can't seem to make it run. This is the code I used (link):

   // create an observer instance
var target = document.querySelector('#something');
console.log(target);
var observer = new WebKitMutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
      console.log("Success");
        //$('#log').text('input text changed: "' + target.text() + '"');
        //console.log(mutation, mutation.type);
    });    
});
observer.observe(target, { attributes: true, childList: true, characterData: true });
//observer.disconnect(); - to stop observing

// test case
setInterval(function(){
    document.querySelector('#something').innerHTML = Math.random();
},1000);

The above code doesn't seems to work. However if I modify the same code with a bit of jQuery, everything seems to work just fine (Demo here). Is there something I'm missing from the docs or I'm just misinterpreting the observer feature.

Universal Electricity
  • 775
  • 1
  • 12
  • 26
I_Debug_Everything
  • 3,776
  • 4
  • 36
  • 48

3 Answers3

15

You need subtree: true

http://jsfiddle.net/6Jajs/1/

The inner text would normally be a child text() element in the DOM. Without the subtree it will only watch the element itself.

There is possible confusion surrounding "characterData" (https://developer.mozilla.org/en-US/docs/Web/API/CharacterData), but it seems that that applies only to nodes that directly contain text. The DOM is structured so that most markup elements contain mixed type which optionally include a child text node (which in turn would implement characterData, but would be a child of the targeted node).

Matt Whipple
  • 7,034
  • 1
  • 23
  • 34
  • Thanks for the clarification. I should do more research before jumping to questioning. :) – I_Debug_Everything Jun 22 '14 at 12:56
  • It's also an argument to stick with tools like jQuery even as native JavaScript and the DOM API have become more powerful. The underlying API doesn't (and IMO shouldn't) hide these types of technical details, so there's benefit to an additional layer of usability abstraction. – Matt Whipple Jun 22 '14 at 13:13
1

To Watch Text or Input changes

use

characterData: true

Example:

var target = document.querySelector('#text');

var observer = new MutationObserver(function(mutations) {
  
  mutations.forEach(function(mutation) {
    console.log(mutation.type);
  });
});

var config = {
 
  characterData: true,
        subtree: true,

};

observer.observe(target, config);

// otherwise
observer.disconnect();
observer.observe(target, config);
<div id="text" contenteditable="true">characterData:true</div>

To Watch Child or Append Text or Inserting Dom

childList:true

Example:

var target = document.querySelector('#text');

var observer = new MutationObserver(function(mutations) {
  
  mutations.forEach(function(mutation) {
    console.log(mutation.type);
  });
});

var config = {

  childList: true,
      subtree: true,
      };

observer.observe(target, config);

// otherwise
observer.disconnect();
observer.observe(target, config);
<div id="text" contenteditable="true">characterData:true</div>

<button onclick="testappend();
function testappend(){
document.getElementById('text').append('tesxt')
}">append</button>

To Watch dom Attributes

   attributes: true

Example

var target = document.querySelector('#text');

var observer = new MutationObserver(function(mutations) {
  
  mutations.forEach(function(mutation) {
    console.log(mutation.type);
  });
});

var config = {
 
  characterData: true,
   attributes: true,
 
};

observer.observe(target, config);

// otherwise
observer.disconnect();
observer.observe(target, config);
<div id="text" contenteditable="true">characterData:true</div>

<button onclick="testappend();
function testappend(){
document.getElementById('text').classList.add('tesxt')
}">add class</button>

<button onclick="setat();
function setat(){
document.getElementById('text').setAttribute('data-prop','text')
}">set attribute</button>
attribute old value

https://developer.mozilla.org/en-US/docs/Web/API/MutationObserverInit/attributeOldValue

Balaji
  • 9,657
  • 5
  • 47
  • 47
0

Simple Example:

<div contentEditable id="myID">MUST EDIT NOW</div>
<script>
let x = new MutationObserver(   function(){ alert('DETECTED'); }   );
x.observe( myID , {subtree:true,characterData:true} );
</script>

See Example Live: https://jsfiddle.net/mbo9eLt5/

proseosoc
  • 1,168
  • 14
  • 23