title: MutationObserver callback not called if disconnect called immediately after modifying the DOM
body: <p>I'm building an undomanager, similar to the W3C undomanager that's not quite yet ready in the various browsers. I implemented a simply transact call that calls a callback while watching for changes to the DOM, and then adds the necessary structures to an array that can later be used to undo (or redo) the change.</p>
  
  <p>A simple example:</p>
  
  <pre><code>function transact(callback){
      /* Watch content area for mutations */
      observer = new MutationObserver(function(){
          /* TODO: collect mutations in here */
          alert('Mutations observed');
      });
      observer.observe(document.getElementById('content'), {
        attributes: false,
        childList: true,
        characterData: false,
        subtree: false
      });
  
      /* Perform the callback */
      callback();
  
      /* Stop observing */
      //observer.disconnect();
      setTimeout(function(){ observer.disconnect();}, 1);
  
  }
  </code></pre>
  
  <p>To use this:</p>
  
  <pre><code>transact(function(){
      var p = document.createElement('p');
      p.innerHTML = 'Hello';
      document.getElementById('content').appendChild(p);
  });
  </code></pre>
  
  <p>If I call <code>observer.disconnect()</code> immediately, the mutation observer never reaches the <code>alert</code> call, but if I use setTimeout, it works fine.</p>
  
  <p>I would be perfectly happy to live with the setTimeout call, the only problem seems to be that for larger changes, you have to delay the disconnect as much as 800 milliseconds.</p>
  
  <p>It is almost as if the disconnect happens before the DOM change has actually been completed, and so nothing is detected.</p>
  
  <p>This happens in both Firefox 25 and Chrome 32.</p>
  
  <p>I thought for a second that because <code>observer</code> is a local variable, perhaps it goes out of scope too soon, but changing it to a global variable didn't help. I have to delay the call to <code>disconnect()</code> to give the DOM a chance to catch up it seems.</p>
  
  <p>Is this a browser bug? Is there a better way to call <code>disconnect()</code> as soon as the DOM is ready again?</p>