0

I have a situation where an anchor fires the 'click' event before the input, which loses the focus and fires the 'focusout' event.

To be clear, I write something in the input and then I click the anchor. I'm expecting the 'focusout' event to be written to console first and then the 'click' event.

I'm not able to reproduce this in a dummy app like in the code below, it only reproduces in the web app I'm working on, which I can't share here.

<a href="#" id="a">click me</a>
<input type="text" id="t">

<script>
document.querySelector("#a").addEventListener('click', function(e) {
  console.log('click');
});

document.querySelector("#t").addEventListener('focusout', function(e) {
  console.log('focusout');
});
</script>

Any idea how could it be possible for anchor to fire the 'click' event first before the input firing 'focusout' event?

I'm pretty dazzled how it's actually possible... I can't see how in the world, even if I wanted to, be able to make the 'click' fire first. I checked several times the event object in watcher in Chrome dev tools and I can't see anything peculiar

I'm using latest Chrome on Windows 10

Don Box
  • 3,166
  • 3
  • 26
  • 55
  • Assuming you are entering some text in the input field and then clicking on the "click me" link when finished, then it seems like you would expect the browser to register both events at the same time (in other words the click and focus change seem to be happening simultaneously). At that point, I am not sure how the browser decides the order to handle the event listeners. Maybe I am misunderstanding the interaction pattern you are following and why you would expect one event to fire before the other? – benvc Jan 11 '19 at 17:20
  • @benvc Sorry, I am so tired, I messed it up. Please have a look again. Thanks – Don Box Jan 11 '19 at 17:29
  • Pretty hard to help you if you don't show your actual code. – Etheryte Jan 11 '19 at 17:31
  • Please explain your question better, as it is now it is unclear. focusout, change, onchange, onkey-- require you to move away focus from the input. – dev101 Jan 11 '19 at 17:32
  • @dev101 I added few more words to be crystal clear. Does it works for you? – Don Box Jan 11 '19 at 17:52
  • I understand it now. Yes, focusout event is fired first in the console log in Chrome 71 on my PC. – dev101 Jan 11 '19 at 18:03

3 Answers3

0

The change event doesn't fire until the input loses focus. You can use onkeypress instead.

wimbletim
  • 103
  • 1
  • 10
  • @DonBox Did you edit your question? I swear your second listener was listening to change events. – wimbletim Jan 11 '19 at 20:07
  • Sorry for that yes, I did it very quickly after I posted it. It's basically same issue but not for change – Don Box Jan 12 '19 at 06:08
0

Ironically enough, it seems like jQuery .focusout / .click conflict has the exact opposite problem as you. From what I'm reading around the web it seems like the general concesus is that the HTML specification doesn't actually specify the order of events and it is up to the browser to implement however they see fit. However, in your case I would certainly expect focusout to happen first, tho clearly it isn't. Have you tried "onblur" instead?

Leroy Stav
  • 722
  • 4
  • 12
  • I replaced 'change' with 'blur' and 'click' is still written first... I cannot see for the life of me how is this possible. Again, this happen only in this web app I am working, I can't reproduce it in the dummy code app. – Don Box Jan 11 '19 at 17:56
  • I can't see how in the world, even if I wanted to, be able to make the 'click' fire first. I checked several times the event object in watcher in Chrome dev tools and I can't see anything peculiar – Don Box Jan 11 '19 at 17:58
  • Well then you're doing something else somewhere else... if you can't reproduce it then it isn't real. Do you have a setTimeout somewhere? – Leroy Stav Jan 11 '19 at 18:51
  • Thanks, I thought about that too, it's the only logical explanation. But I haven't yet been able to find it. I even tried adding an event handler to the 'focusout' event on the input in the Chrome dev console, but it's still not being called first, the 'click' event is fired first t!!! – Don Box Jan 11 '19 at 19:13
  • If there was a setTimeout, I think call stack should had showed it on the focusout event but there isn't any – Don Box Jan 11 '19 at 20:03
  • I was just grasping at straws, really... any other 3rd party libraries that might be messing with the jQuery handling? You sure you aren't able to duplicate it by adding more code? lol – Leroy Stav Jan 11 '19 at 20:31
  • You need to debug that from the ground up step-by-step. – dev101 Jan 11 '19 at 21:35
  • Jesus Christ, I've found it! – Don Box Jan 12 '19 at 06:37
0

I found it! This is one of those things which doesn't let you sleep well.

The issue was somewhere else, in some library, there is a mousedown handler on the anchor with a e.preventDefault():

http://jsfiddle.net/vynd7kgj/

This sucks. I don't know if I should cry or laugh.

Why would you want to do something like this?

Don Box
  • 3,166
  • 3
  • 26
  • 55
  • There are plenty of perfectly valid reasons to `e.preventDefault()`... just fyi :-) – Leroy Stav Jan 24 '19 at 06:32
  • Also, hat being said, this implies that your question was wrong... and honestly we would quite possible (and even likely) have told you that that is what was happening had your question been correctly worded. You said that the click event happens *first*. Based on my tests, the click event is *the only one that happens*. The blur event *doesn't fire at all*. For next time it is important to be perfectly clear about what is happening so we can better help you! – Leroy Stav Jan 24 '19 at 06:40