简体   繁体   English

事件侦听器回调在另一个事件侦听器的回调中设置时立即触发。 ReactJS

[英]Event Listener Callback Fires Immediately When Set Inside The Callback of Another Event Listener. ReactJS

With a create-react-app boilerplate setup, I have an input field with an onFocus event passed.通过 create-react-app 样板设置,我有一个传递了 onFocus 事件的输入字段。 Within this onFocus callback I'm setting a click eventlistener on window.document.在这个 onFocus 回调中,我在 window.document 上设置了一个点击事件监听器。

When the input field is focused why does the clickHandler callback fire immediately?当输入字段被聚焦时,为什么 clickHandler 回调会立即触发?

function App() {

  const clickHandler = (e) => {
      console.log("clicked");
      window.document.removeEventListener("click", clickHandler)
  } 

  const focusHandler = (e) => {
      console.log('onFocus');
      e.stopPropagation()
      window.document.addEventListener("click", clickHandler)  
  }

  return (
   <div className="App">
          <input onFocus={focusHandler} />
    </div>
  );

When you click on the input, few events occur such as mousedown , mouseup , focus click .当您单击输入时,会发生一些事件,例如mousedownmouseupfocus click (fyi - click happens when a mousedown and mouseup event occur on the same element). (仅供参考 - 当同一元素上发生 mousedown 和 mouseup 事件时发生单击)。 In chrome,focus handler is executed first and then the click handler is executed (if the handlers exist).在 chrome 中,首先执行焦点处理程序,然后执行单击处理程序(如果处理程序存在)。

Now, in your code when you click on the input, focusHandler is executed where a click handler is attached to the window .现在,在您的代码中,当您单击输入时,将执行focusHandler ,其中单击处理程序附加到window By the time the js engine finishes the execution of focusHandler , there is a click handler registered already.当 js 引擎完成focusHandler的执行时,已经注册了一个点击处理程序。 So as soon as focusHandler is executed, the js engine realises that 'ah, there is a clickHandler that I need to execute it.所以一旦执行了focusHandler ,js引擎就会意识到‘啊,有一个clickHandler我需要执行它。 Let me do it' .让我做吧' Hence your clickHandler fires immediately.因此,您的 clickHandler 会立即触发。

You can test it by attaching event handler in a setTimeout .您可以通过在setTimeout中附加事件处理程序来测试它。 In below code, js engine has no clickHandler to execute after focusHandler execution is finished.在下面的代码中,js引擎在focusHandler执行完成后没有clickHandler执行。 So click handler won't fire immediately.所以点击处理程序不会立即触发。

const focusHandler = e => {
    console.log("onFocus");
    e.stopPropagation();
    setTimeout(() => window.addEventListener("click", clickHandler), 1000);
  };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM