JS 处理事件与侦听器并行发生 运行

JS processing events happening parallel to listeners running

我不确定,一些JS代码是如何生成事件的运行。

例如在这种情况下:

<div id="div1"> text </div>
<div id="div2"> text </div>

div2.onpointermove = (e) => {
    console.log("old handler");
};
div1.onpointerdown = (e) => {
    div2.onpointermove = (e) => {
        console.log("new handler");
};  };

布局:

+-----+-----+
|div1 | div2|
+-----+-----+

场景:

  1. pointerdown 在 div1
  2. 的边缘像素上
  3. 指针移出 div1 并进入 div2

当 JS 代码在单线程上运行时,用户可以将鼠标平行移动到某些 JS 代码 运行。我想知道,事件是如何生成然后处理的,而一些JS代码是运行?

可能的时间表:

A)

  1. 指针指向 div1
  2. 的边缘像素
  3. 将鼠标移到div2平行事件监听JS代码运行
  4. 当 JS 代码处理事件侦听器时,鼠标事件 排队
  5. 调用div1.onpointerdown
  6. 添加新处理程序div2.onpointermove
  7. 使用 组侦听器
  8. 处理排队的鼠标事件
  9. “新处理程序”打印在控制台上

B)

  1. 指针指向 div1
  2. 的边缘像素
  3. 将鼠标移到div2平行事件监听JS代码运行
  4. 当JS代码处理事件监听器时,鼠标事件被忽略
  5. 调用div1.onpointerdown
  6. 添加新处理程序div2.onpointermove
  7. 再次开始注册活动
  8. div2 上的指针移动丢失,控制台上没有打印任何内容(如果鼠标在 div1.onpointerdown 完成处理后没有移动,并且 JS 之前没有比较鼠标位置-处理代码块后)

C)

  1. 指针向下指向 div1
  2. 的边缘像素
  3. 将鼠标移到div2平行事件监听JS代码运行
  4. 当 JS 代码处理事件侦听器时,鼠标事件 排队 与当前的 old 事件集一起处理听众
  5. 调用div1.onpointerdown
  6. 添加新处理程序div2.onpointermove
  7. 使用、记录的事件侦听器
  8. 处理队列中的下一个事件
  9. “旧处理程序”打印在控制台上

我不知道,会发生哪种情况,或者是否取决于浏览器?

pointerdownpointermove 仅用于示例目的,我对这些确切事件的怪癖不感兴趣,而是对事件如何发生的更一般概念感兴趣 generated/saved/ignored/handled 而一些 JS 代码是 运行,它为那些与代码块并行发生的事件添加事件处理程序 运行.

此外,是否存在通用行为,或者是否存在特定于实现的细节?

通常,使用方法 A - 事件排队,然后在 JS 事件循环完成先前处理程序的执行后处理。

但是,快速且连续(不离散)的事件,如滚动或鼠标移动(与点击或按键相反)可以被引擎限制,因此如果处理它们的 JS 代码花费很长时间。这可能相当于丢弃一些事件(方法 B)——但你怎么知道?

至于方法C,没用过。排队的是事件,而不是 运行 已注册处理程序的任务。这在删除事件侦听器时尤为重要 - 在您调用 removeEventListener 后,您可以确定它不会被再次调用,即使事件仍在排队中可能会触发它。但是,对于安装新的事件侦听器,并没有真正区分差异的方法 - 代码无法判断事件是在安装侦听器之前还是之后触发的,因此这为浏览器提供了一些优化余地。