我为输入添加了几个事件监听器:
['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
我认为这是由事件冒泡引起的。输入符号后,这些事件侦听器的回调不会立即添加到回调队列中,但是在事件被冒泡后会添加它们,所以我们在那里看到混合执行。
BUT 变异观察者也被添加到document
示例中,所以应该在那里应用事件冒泡之类的东西,不是吗?
所以,我的问题是:
是否有执行事件监听器回调和MutationObserver回调的确切顺序?我可以信任上面的执行命令,还是可以改变?
另外请解释我的想法是否正确,如果是,为什么在最后一个示例中输出
keydown event is handled
Handled mutation records: ...
input event is handled
但不是:
Handled mutation records: ...
keydown event is handled
input event is handled