何时触发MutationObserver回调?

时间:2013-01-28 14:51:13

标签: javascript dom browser dom4

我知道在DOM更改后的某个时候可能会调用MutationObservers回调。但问题是:这些回调的时机是什么时候? 回调是否进入浏览器的事件队列?如果是这样,他们什么时候进入队列?

是回调:

  • 在DOM突变发生后立即调用,
  • 只要操作DOM的函数完成就会调用,
  • 在调用堆栈为空时调用,
  • 在DOM突变发生后立即排队,
  • 只要操作DOM的函数完成,
  • 就会排队,或者
  • 在其他时间?

例如,如果执行以下代码(使用setZeroTimeout defined here):

var target = document.body;

new MutationObserver(function(mutations) {
  console.log('MutationObserver');
}).observe(target, {
  attributes: true,
  childList: true,
  characterData: true
});


// Post message
setZeroTimeout(function () { console.log('message event'); });
// DOM mutation
target.setAttribute("data-test", "value");

在“消息事件”之前或之后打印“MutationObserver”吗? 或者它是实现定义的吗?

我在Chromium 26上的“消息事件”之前得到“MutationObserver”,尽管DOM突变是在消息发布之后。也许这表明使用事件队列MutationObserver回调是

我已经搜索过HTML规范,DOM规范或浏览器实现文档,但我没有发现与此行为相关的任何内容。

有关MutationObservers回调时间的任何解释或文档吗?

2 个答案:

答案 0 :(得分:18)

MutationObservers是异步触发的,但是“很快”,这意味着它们会在队列中的其他内容之前触发,例如布局,绘制或触发事件。

这可以改善失去同步性,因为在观察者有机会做出反应之前,您不必担心屏幕闪烁或其他不良事件。

在开发者笔记中,他们谈到了“微任务结束”时序模型。我同意这个记录很少。

答案 1 :(得分:14)

根据updated DOM spec from WHATWG,我将在两年后回答我自己的问题。

如规范所示:

  

要对突变观察者复合微任务进行排队,请运行以下步骤:

     
      
  1. 如果设置了变异观察者复合微任务排队标志,则终止这些步骤。
  2.   
  3. 设置变异观察者复合微任务排队标志。
  4.   
  5. 对复合微任务进行排队以通知变异观察者。
  6.   

while"排队复合微任务"链接到a section in the HTML spec解释微任务队列模型。

因此,我们可以得出结论,MutationObserver回调是作为微任务触发的,它确实比the answer of @Scott Miles above建议的任务队列任务更早。

为了进一步了解事件循环和处理模型,HTML规范的the Event Loop section将是完美的。

就个人而言,我很高兴看到MutationObserver是标准的一部分,并且有一个记录良好且一致的时序模型。使用MutationObserver s supported in most modern browsers,我认为它们现在可用于生产。