关于浏览器事件循环


上代码

<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
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容