javascriptmutation-observersmutationmutation-events

MutationObserver and querySelectorAll


I am currently learning Javascript and one of my chapters is "Mutation Observer". I am trying to create a simple function which detects if a new div was added to the page and display it in the console. However, I am getting this message and I struggle to find a solution how to fix this error. I will be very grateful if someone can explain to me what I am doing wrong. Thank you in advance!

Uncaught TypeError: Failed to execute 'observe' on 'MutationObserver': parameter 1 is not of type 'Node'.

So far this is the code I wrote:

document.getElementById("Button").onclick = function(){
  var Add = document.createElement('div');
    Add.setAttribute("class", "Alpha");
    Add.appendChild(document.createTextNode("Test"));
    document.getElementById('Frame').appendChild(Add);
};

var Divs = document.querySelectorAll("div");
var Observer = new MutationObserver(function(mutations){
  mutations.forEach(function(mutation){
    for(var i = 0; i <= mutation.addedNodes.length; i++){
      if(!(mutation.addedNodes[i] == null)){
        console.log(mutation.addedNodes[i].innerHTML);
      }
    }
  });
});
Observer.observe(Divs, {childList: true, subtree:true});
.Alpha{
  color:red;
}
<button id="Button">Generate a new div</button>
<div id="Frame"></div>


Solution

  • The issue is explained in the error message. The observe function expects a Node but you're assigning the return value of querySelectorAll lookup which actually returns a NodeList (so one or many Nodes). Even if it finds nothing, it'll return an empty NodeList and still be invalid.

    In your instance, you appear to be pushing items into a DIV with an id of Frame so we'll attach our MutationObserver onto that and watch for any changes to its children. Finally, we'll push any changed nodes into an array and console log the contents so you can see what it's capturing,

    var target = document.getElementById('Frame');
    var insertedNodes = [];
    var Observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            for(var i = 0; i < mutation.addedNodes.length; i++) {
                insertedNodes.push(mutation.addedNodes[i]);
            }
        });
    });
    
    Observer.observe(target, {
        childList: true,
        subtree:true
    });
    
    console.log(insertedNodes);