52

I would like to use a MutationObserver object to observe changes to some of my DOM nodes.

The docs give an example of creating a MutationObserver object and registering it on a target.

// select the target node var target = document.querySelector('#some-id'); // create an observer instance var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { console.log(mutation.type); }); }); // configuration of the observer: var config = { attributes: true, childList: true, characterData: true }; // pass in the target node, as well as the observer options observer.observe(target, config); 

Say I have the code above, but just under it, I place this code:

var target2 = document.querySelector('#some-other-id'); var config2 = {attributes: true, subtree: true}; observer.observe(target2, config2); 

Will observer:

  • now be observing 2 targets?
  • will it stop observing target?
  • will it decide not to observe target2?
  • will it throw an error?
  • or will it exhibit some other behavior?
0

2 Answers 2

53

The observer will now be watching two targets - target and target2 per your definitions. No error will be thrown, and target will not be "unregistered" in favor of target2. No unexpected or other behaviors will be exhibited.

Here is a sample which uses the same MutationObserver on two contenteditable elements. To view this, delete the <span> node from each contenteditable element and view the behavior span across both observed elements.

<div id="myTextArea" contenteditable="true"> <span contenteditable="false">Span A</span> </div> <div id="myTextArea2" contenteditable="true"> <span contenteditable="false">Span B</span> </div> 

var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { //console.log($(mutation.removedNodes)); // <<-- includes text nodes $(mutation.removedNodes).each(function(value, index) { if(this.nodeType === 1) { console.log(this) } }); }); }); var config = { attributes: true, childList: true, characterData: true }; observer.observe($('#myTextArea')[0], config); observer.observe($('#myTextArea2')[0], config); 

JSFiddle Link - demo

Note that I have recycled the same config for this first demo, but, placing a new config will be exclusive to that observed element. Taking your example as defined in config2, if used on #myTextArea2, you'll not see the logged node per the configuration options, but notice that the observer for #myTextArea is unaffected.

JSFiddle Link - demo - configuration exclusiveness

Sign up to request clarification or add additional context in comments.

16 Comments

Very nice! Though I wonder if this works consistently in all browsers, and I wonder if it's consistent if you happen to observe an element within an element you started observing?
Something to also note is that observing the same target more than once, will not result in multiple calls to the callback for changes to that element.
There's a problem with this: how do we unobserve one of the element we're observing? It seems like the disconnect() method will make a MutationObserver stop observing all the elements! This means there's no cleanup per element, which means possibility of memory leaks!!
Well I guess you have to disconnect and then re-observe just the elements you need. I'd almost prefer to pass it a live HTMLCollection and have it watch all of those elements automatically even when nodes are added and removed.
@minseong Seems there are only two options: use one MO per element, or call disconnect on a single MO then observe again on all the elements except for the one you no longer wish to observe. There's also a spec discussion on adding an API for it: github.com/WICG/webcomponents/issues/940
|
1

(This should be a comment to the accepted answer but I don't have enough reputation)

When you have a MutationObserver m that is currently observing multiple nodes and you want to "disconnect" from only one node e, you can do the following:

m.observe(e, { attributes: true, attributeFilter: [] }); 

This removes the preexisting observers on e (MDN Docs link) and adds a dummy observer on e.

2 Comments

This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From Review
It should be "attributes".

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.