Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use MutationObserver on multiple nodes?

The following code allows me to listen for class changes on a single node:

var target = $(".right-border")[0]

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

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

 observer.observe(target, config);

If I have a grid of divs, for example, and each div on the right border has a class of right-border, how can I listen for changes on each one? I know that I could create multiple variables:

var target2 = $(".right-border")[1]
var target3 = $(".right-border")[2]

But is there a more efficient way of selecting each node? Is it possible to use a for loop somewhere in the above code that targets each div with a class of right-border?

like image 938
Pat Mellon Avatar asked May 11 '17 17:05

Pat Mellon


People also ask

What is MutationObserver?

The MutationObserver interface provides the ability to watch for changes being made to the DOM tree. It is designed as a replacement for the older Mutation Events feature, which was part of the DOM3 Events specification.

How do you observe DOM changes?

One way to watch for DOM changes in our JavaScript web app is to use the MutationObserver constructor. For instance, we can write: const observer = new MutationObserver((mutations, observer) => { console. log(mutations, observer); }); observer.


2 Answers

You can use jQuery's each method to iterate over all matching DOM nodes and observe its mutations. The code is almost what you already have - notice that target = this which is how each node is targeted.

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

$(".right-border").each(function () {
  var target = this;
  var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
      console.log("Change")
    });
  });

  observer.observe(target, config);
});
like image 77
iblamefish Avatar answered Oct 22 '22 13:10

iblamefish


You can iterate .right-border elements using .each(), call function to create MutationObserver for each element, store the instances of MutationObserver within an array of objects where index of element in collection references MutationObserver instance for that element.

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

var observers = [];

function setObserver(target, index) {
  var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
      console.log("Change")
    });
  });
  observer.observe(target, config);
  observers.push({[index]: observer});
}

$(".right-border").each(function(index, el) {
  setObserver(el, index)
});

Storing of instances of MutationObserver is for purpose of calling .disconnect() on a specific MutationObserver instance if needed; for example

var observer = observers.find(function(el) {
  return +Object.keys(el).pop() === 1
});

observer.disconnect();

or

var observer = observers.filter(function(el) {
  return +Object.keys(el).pop() === 1
});

observer.pop().disconnect();
like image 21
guest271314 Avatar answered Oct 22 '22 11:10

guest271314