Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 事件侦听器回调和MutationObserver回调的执行顺序是否准确?_Javascript_Addeventlistener_Event Loop_Mutation Observers - Fatal编程技术网

Javascript 事件侦听器回调和MutationObserver回调的执行顺序是否准确?

Javascript 事件侦听器回调和MutationObserver回调的执行顺序是否准确?,javascript,addeventlistener,event-loop,mutation-observers,Javascript,Addeventlistener,Event Loop,Mutation Observers,我向输入添加了几个事件侦听器: ['input', 'keydown'].forEach(eventName => { document.getElementById('my-input').addEventListener(eventName, e => { console.log(`${eventName} event is handled'); }) }) 我还向文档中添加了变异观察者: const mutationObserver = new Mut

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

['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
});
['input', 'keydown'].forEach(eventName => {
   document.addEventListener(eventName, e => {
      console.log(`${eventName} event is handled');
   })
})
如果运行此代码,我将看到下一个输出:

keydown事件已处理

已处理输入事件

处理的突变记录:…

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

当我在输入字段中输入symbol时,此输入的所有已注册事件侦听器都将添加到回调队列中。之后,变异观察者回调也被添加到回调队列中——因此,我们看到变异观察者回调是在事件侦听器回调之后执行的

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

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
});
['input', 'keydown'].forEach(eventName => {
   document.addEventListener(eventName, e => {
      console.log(`${eventName} event is handled');
   })
})
我看到下一个输出:

keydown事件已处理

处理的突变记录:…

已处理输入事件

我想这是由一连串事件引起的。这些事件监听器的回调不会在输入符号后立即添加到回调队列中,而是在事件冒泡后添加,所以我们可以看到混合执行

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

所以,我的问题是:

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

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

keydown事件已处理

处理的突变记录:…

已处理输入事件

但不是:

处理的突变记录:…

keydown事件已处理


输入事件被处理

显然,它是由事件冒泡引起的,但是在DOM/JS规范中没有定义任务(事件)和微任务(MutationObserver)的执行顺序,因此浏览器以不同的方式实现它,因此您不应该依赖当前状态,因为它可能在将来发生变化。