14

How can I disconnect my mutation observer from its callback function? The changes are being observed as they should, but I would like to disconnect the observer after the first change. Since the observer variable is out of scope, it's not disconnecting as it should. How can I pass the observer variable to the callback function so the code will work?

function mutate(mutations) {
  mutations.forEach(function(mutation) {
    if ( mutation.type === 'characterData' ) {
      console.log('1st change.');
      observer.disconnect(); // Should disconnect here but observer variable is not defined.
    }
    else if ( mutation.type === 'childList' ) {
      console.log('2nd change. This should not trigger after being disconnected.');
    }
  });
}

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

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

  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>
<body>
  <div id="mainContainer">
    <h1>Heading</h1>
    <p>Paragraph.</p>
  </div>
</body>
GTS Joe
  • 3,612
  • 12
  • 52
  • 94
  • Does this answer your question? [MutationObserver disconnect() call inside callback function](https://stackoverflow.com/questions/32354710/mutationobserver-disconnect-call-inside-callback-function) – d4nyll May 08 '21 at 18:49

1 Answers1

23

The easiest way would be to adjust your callback

function mutate(mutations) {

to

function mutate(mutations, observer) {

because the observer instance associated with the mutations is automatically passed as the second parameter to the mutation handler function.

Then you can call observer.disconnect() at whichever time you need it.

loganfsmyth
  • 156,129
  • 30
  • 331
  • 251
  • Yes, but then how would you pass the observer variable as an argument to mutate()? Could you elaborate your code so I cant test it? I'm interested to see how your code would work. – GTS Joe Dec 25 '16 at 21:31
  • 2
    You don't have to, `MutationObserver` automatically passes it, the same way it passes `mutations`. – loganfsmyth Dec 25 '16 at 21:45
  • How is it that JS is able to do this? I've never known a programming language that automatically passes arguments for you. Does this special feature have a name in JS? – GTS Joe Dec 25 '16 at 21:55
  • 1
    @guest271314 I tried loganfsmyth's approach and yes, it does work. I'm just trying to understand why it works to actually learn something about JS. – GTS Joe Dec 25 '16 at 22:04
  • @loganfsmyth Was erroneously still including `document.observer` when tried. – guest271314 Dec 25 '16 at 22:06
  • 1
    @GTSJoe Disregard previous comment. loganfsmyth is correct. Was incorrect, here. _"callback The function which will be called on each DOM mutation. The observer will call this function with two arguments. The first is an array of objects, each of type MutationRecord. The second is this MutationObserver instance."_ https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver – guest271314 Dec 25 '16 at 22:08
  • 3
    You can also use `this.disconnect()` in the callback because it's automatically bound by the API. – wOxxOm Dec 26 '16 at 00:28
  • @loganfsmyth Can we pass custom parameters (like a string data) to the `mutate()` function? If so, how can we do it? – UnahD May 10 '18 at 07:05
  • @UnahD Rather than commenting on existing questions, it would be best to create a new question, and spell out what you're actually trying to do with that data. – loganfsmyth May 10 '18 at 07:22