MutationObserver Limit

1.6k views Asked by At

How can I implement a counter to a mutation observer to limit the number of changes it watches before it disconnects? In the fiddle I included, the idea is that once var count is greater than one, the observer should disconnect. But since the variable resets each time the observer handler is called, it doesn't work. How can I implement what I'm trying to do?

function mutate( mutations, observer ) {
 var count = 0;
 console.log('\nThe following mutation(s) occurred:');

 mutations.every(function(mutation) {
  if ( mutation.type === 'attributes' ) {
   console.log('Attribute change.');
  }
  else if ( mutation.type === 'characterData' ) {
   console.log('Text change.');
  }
  else if ( mutation.type === 'childList' ) {
   if ( count > 1 ) {
    observer.disconnect();
    console.log('Disconnected.');
    return false;
   }

   console.log('Element change.');
  }

  count++;
  console.log('Count: ' + count);

 });
}

document.addEventListener('DOMContentLoaded', function() {
 setTimeout(function() {
  document.getElementById('photo').src = 'http://i.imgur.com/Xw6htaT.jpg';
  document.getElementById('photo').alt = 'Dog';
 }, 2000);

 setTimeout(function() {
  document.querySelector('div#mainContainer p').innerHTML = 'Some other text.';
 }, 4000);

 setTimeout(function() {
  jQuery('div#mainContainer').append('<div class="insertedDiv">New div!<//div>');
 }, 6000);

 setTimeout(function() {
  jQuery('div.insertedDiv').remove();
 }, 8000);

 var targetOne = document.querySelector('div#mainContainer');
 var observer = new MutationObserver( mutate );
 var config = { attributes: true, characterData: true, childList: true, subtree: true };

 observer.observe(targetOne, config);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="mainContainer">
  <h1>Heading</h1>
  <p>Paragraph.</p>
  <img src="https://i.stack.imgur.com/k7HT5.jpg" alt="Photo" id="photo" height="100">
</div>

1

There are 1 answers

0
loganfsmyth On

You could capture the counter in a closure scope, e.g.

function mutate( mutations, observer ) {
  // ...
}

// ...
var observer = new MutationObserver( mutate );

to

function createMutateHandler() {
  var count = 0;

  return function mutate( mutations, observer ) {
    // ...
    count++;
  };
}

// ...
var observer = new MutationObserver( createMutateHandler() );

so the count variable exists alongside the mutate function without being a global.

As long as you don't need to access count outside of mutate this should work great.