1

With a create-react-app boilerplate setup, I have an input field with an onFocus event passed. Within this onFocus callback I'm setting a click eventlistener on window.document.

When the input field is focused why does the clickHandler callback fire immediately?

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>
  );
succeed
  • 834
  • 1
  • 11
  • 28
  • 4
    That is because of the time the events are triggered.`Focus` happens during the mouse down. And so ur function handler is called. `Click` happens on `mouseup`. Due to this, your click gets called because, by the time mouse up happens, your focus handler is called and `click` event is set. – Panther May 10 '20 at 04:09
  • I can't produce the problem you mention here. Also, you add the listener to `windows` instead of `window.document` in the `focusHandler` function. Probably a typo when you move the example here? – devserkan May 10 '20 at 04:18
  • @devserkan yeah was a typo that I have now fixed – succeed May 10 '20 at 05:35
  • @Panther yes that's correct. Holding mouse down without releasing console.logs only the focus and when releasig logs the click. Cheers – succeed May 10 '20 at 06:01

1 Answers1

0

When you click on the input, few events occur such as mousedown, mouseup, focus click. (fyi - click happens when a mousedown and mouseup event occur on the same element). In chrome, focus handler is executed first and then the click handler is executed (if the handlers exist).

Now, in your code when you click on the input, focusHandler is executed where a click handler is attached to the window. By the time the js engine finishes the execution of focusHandler, there is a click handler registered already. So as soon as focusHandler is executed, the js engine realises that 'ah, there is a clickHandler that I need to execute it. Let me do it' . Hence your clickHandler fires immediately.

You can test it by attaching event handler in a setTimeout. In below code, js engine has no clickHandler to execute after focusHandler execution is finished. So click handler won't fire immediately.

const focusHandler = e => {
    console.log("onFocus");
    e.stopPropagation();
    setTimeout(() => window.addEventListener("click", clickHandler), 1000);
  };
gdh
  • 13,114
  • 2
  • 16
  • 28