UI 事件处理程序中的 setTimeout 宏任务

setTimeout macrotask in the UI event handler

我写了以下简单的反应组件

在 onBlur 事件处理程序中,我通过 setTimeout

创建了一个新的宏任务
function App() {
  const onBlur=()=>{
    console.log('onBlur')
    setTimeout(() => {
      console.log('setTimeout')
    }, 0);
  }

  const onClick=()=>{
    console.log('onClick')
  }
  
  return (
    <div className="App">
      <div id="first" onClick={onClick}>aaa</div>
      <div id="second" contentEditable onBlur={onBlur} suppressContentEditableWarning>qq</div>
    </div>
  );
}

然后

1、我把鼠标移到第二个div

2、然后我点击第一个div

它在控制台中按以下顺序打印出来

onBlur

设置超时

点击

我的问题是为什么 setTimeout 显示在 onClick 之前;

感谢您的回答;请帮我;非常感谢;

因为模糊事件是从 mousedown 事件触发的,而 click 事件由 mousedownmouseup 组成。

const d1 = document.querySelector("div");
const d2 = document.querySelector("div[contenteditable]");

d1.addEventListener("mousedown", ({type}) => { 
  console.log(type);
  setTimeout(() => console.log("timeout from %s", type), 0);
});
d1.addEventListener("click", ({type}) => console.log(type));
d1.addEventListener("mouseup", ({type}) => console.log(type));
d2.addEventListener("blur", ({type}) => {
  console.log(type);
  setTimeout(() => console.log("timeout from %s", type), 0);
});
d2.focus();

/* expected output:
mousedown
blur
timeout from mousedown
timeout from blur
mouseup
click
*/
<div>CLICK ME</div>
<div contenteditable>focused element</div>

因此,当您释放鼠标指针时,模糊事件已经被触发并且 0 超时也有时间执行,除非您可以在 Chrome,它们的最小超时时间为 1 毫秒。