8

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.

Community
  • 1
  • 1
Mark Bennett
  • 105
  • 2
  • 8
  • 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 Apr 15 '16 at 19:34
  • 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 Apr 18 '16 at 10:58

3 Answers3

4

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.

Marvin Medeiros
  • 202
  • 4
  • 22
  • 1
    `mousedown` has the disadvantage of firing immediately on the start of a click. While fine in most cases, users that click and hesitate will be unable to go back on their decision to click. – Chris Apr 18 '16 at 10:54
0

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

0

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.

Hugo S. Mendes
  • 1,076
  • 11
  • 23