7
votes

Looking for an explanation to the answers provided here and here.

Put simply, I have two elements. An input with an onBlur event, and a div with an onClick event. Without any special handling, when I blur the input by clicking the div, the onBlur event is fired, while the onClick event is not.

However, if I put a setTimeout inside the blur event handler, both event handlers are called when I click on the div. Why does this work?

HTML:

<input type="text" name="input" id="input1" />
<div id="div1">Focus the input above and then click me. (Will see 1 alert)</div>
<br/>
<input type="text" name="input" id="input2" />
<div id="div2">Focus the input above and then click me. (Will see 2 alerts)</div>

Javascript:

$(document).ready(function() {
  function clickHandler() {
    alert('Click!');
  }

  function blurHandler() {
    alert('Blur!');
  }

  $('#input1').on('blur', function() {
    blurHandler();
  })
  $('#input2').on('blur', function() {
    window.setTimeout(blurHandler, 200);
  })

  $('#div1').on('click', function() {
    clickHandler();
  })
  $('#div2').on('click', function() {
    clickHandler();
  })
});

Fiddle demo is here.

3
I would guess that for both this and other examples, the answer has to do with particular details of what exactly the event handlers do. Note that if you replace alert with console.log you get two reactions from both elements. This implies that it is the alert and not the blur/click combination that tells.Jon
It might be educational to note that clicking on the bottom box without releasing the mouse button for a fraction of a second (200ms, to be exact ;) ) prevents the second event from being fired too.Chris

3 Answers

3
votes

It happens because the blur event occurs before the click. The alert() method stops the execution of the script and once stopped, the click event will not fire after you dismiss the alert box. Using the setTimeout() method at the blur handler, you are actually allowing the click event to be fired.

i sugest you to listen to mousedown instead of click. The mousedown and blur events occur one after another when you press the mouse button, but click only occurs when you release it.

0
votes

This is because of the modal nature of alert(). Try using console.log() instead and you will see that both will get called.

0
votes

the setTimeout will fire the event after the time you defined.. so you'll have more time to click on the text.

in the other hand, the first input doesn't have a time to fire the blur so it's more difficult to fire the click event, but if you click fast enough, you will see two alerts even for the first input.