首页 > 解决方案 > 事件侦听器回调和 MutationObserver 回调的执行顺序是否准确?

问题描述

我在输入中添加了几个事件侦听器:

['input', 'keydown'].forEach(eventName => {
   document.getElementById('my-input').addEventListener(eventName, e => {
      console.log(`${eventName} event is handled');
   })
})

我还将突变观察者添加到文档中:

const mutationObserver = new MutationObserver(mutationRecords => {
   console.log('Handled mutation records:', mutationRecords);
});

mutationObserver.observe(document, {
    childList: true,
    attributes: true,
    characterData: true,
    subtree: true,
    attributeOldValue: true,
    characterDataOldValue: true
});

如果我运行此代码,我会看到下一个输出:

keydown event is handled

input event is handled

Handled mutation records: ...

如您所见,最后调用了突变观察者的回调。我认为这是预期的行为,我将解释我如何看待这一点:

当我在输入字段中输入符号时,此输入的所有注册事件侦听器都将添加到回调队列中。在突变观察者回调也被添加到回调队列之后 - 结果我们看到突变观察者回调在事件侦听器回调之后执行

但是如果我将事件侦听器添加到文档中:

['input', 'keydown'].forEach(eventName => {
   document.addEventListener(eventName, e => {
      console.log(`${eventName} event is handled');
   })
})

我看到下一个输出:

keydown event is handled

Handled mutation records: ...

input event is handled

我想这是由事件的冒泡引起的。这些事件侦听器的回调不会在输入符号后立即添加到回调队列中,而是在事件冒泡后稍后添加,因此我们在那里看到混合执行。

但是在示例中还添加了突变观察者document,所以应该在那里应用事件冒泡之类的东西,不是吗?

所以,我的问题是:

事件侦听器回调和 MutationObserver 回调的执行顺序是否准确?我可以相信上面的执行顺序,或者它可能会改变吗?

还请解释我的想法是否正确,如果是,为什么在最后一个示例中的输出是

keydown event is handled

Handled mutation records: ...

input event is handled

但不是:

Handled mutation records: ...

keydown event is handled

input event is handled

标签: javascriptaddeventlistenerevent-loopmutation-observers

解决方案


推荐阅读