上代码
<button id="button" >click</button>
<script>
let button = document.querySelector("#button");
button.addEventListener("click", () => {
Promise.resolve().then(() => console.log("promise1"));
console.log("click1");
});
button.addEventListener("click", () => {
Promise.resolve().then(() => console.log("promise2"));
console.log("click2");
});
button.click();
</script>
执行结果如下
当 click 触发的事件时,会和点击的触发不相同
image.png
click事件过程
image.png
点击事件过程
image.png
经过一系列排查发现
由click 和dispatchEvent等DOM 模拟生成的事件是不可信的,不由浏览器调度。
https://dom.spec.whatwg.org/#dom-event-istrusted
https://dom.spec.whatwg.org/#dispatch-flag
查阅事件流等文档个人得出结论,用户触发的可信事件会由浏览器调度,按照定义事件的顺序执行,而事件内由特定的进程驱动,会将微任务放在下一个事件触发之前执行。
https://w3c.github.io/uievents/#event-flow
3.3事件可以同步或异步调度。
同步事件(同步事件)被视为先进先出模型中的虚拟队列,按照相对于其他事件、DOM变化和用户交互的时间发生顺序进行排序。此虚拟队列中的每个事件都会被延迟,直到前一个事件完成其传播行为或被取消。有些同步事件是由特定的设备或进程驱动的,例如鼠标按钮事件。这些事件由为该组事件定义的事件顺序算法控制,用户代理将按定义的顺序调度这些事件。
异步事件(async events)可以在动作结果完成时调度,与其他事件、DOM中的其他更改以及用户交互无关。
3.4.可信事件
由用户代理生成的事件,无论是作为用户交互的结果,还是作为对DOM进行更改的直接结果,都由用户代理信任,用户代理拥有脚本通过createEvent()方法生成的事件所不具备的权限,可以使用initEvent()方法进行修改,也可以通过dispatchEvent()方法进行调度。受信任事件的受信任属性的值为真,而不受信任事件的受信任属性值为假。
除了点击事件之外,大多数不受信任的事件不会触发默认操作。此事件始终会触发默认操作,即使isTrusted属性为false(保留此行为是为了向后兼容)。所有其他不受信任的事件的行为就像对该事件调用了preventDefault()方法一样。
而 dom 模拟的事件还是遵循 evenloop 的规则
image.png