The issue
According to the W3C, the focusin
event is supposed to fire before the element receives focus, and then the focus
event is supposed to fire after. Instead, focusin
fires after the element receives focus, and after focus
fires.
How things are supposed to be
I have heard from multiple sources including the W3C UI spec (at the bottom of this page) that when an element receives focus, the focusin
event fires before it receives focus, and the focus
event fires after it receives focus, meaning the order of events when clicking into and then out of an input should look like this:
User clicks input
focusin
event fires
input gains focus
focus
event fires
User clicks off
focusout
event fires
input loses focus
blur
event fires
How things are
And yet in practice, it appears that they both fire after the element has received focus, and focus
fires before focusin
. Here’s some code I used:
<!DOCTYPE html>
<html>
<body>
<input id="i1" onfocus="f(event)" onfocusin="f(event)" onfocusout="f(event)" onblur="f(event)">
<script>
const i = document.getElementById('i1');
function f(event) {
console.log(event.type + (document.hasFocus(i) ? ': focused' : ': NOT focused'));
}
</script>
</body>
</html>
The log after clicking into and out of the input looks like this:
focus: focused
focusin: focused
blur: focused
focusout: focused
Which tells me that focusin
is firing after the input gets focus, and not before, and vice versa for blur
(that is, assuming I’m using document.hasFocus()
right)
Not to mention that the order of the events is also wrong, since focusin
and focusout
should be before focus
and blur
, respectively.
If everything were working right, it should look like this:
focusin: NOT focused
focus: focused
focusout: focused
blur: NOT focused
This appears to work the same on Firefox and Chrome. Is something wrong with my browsers, or did I code something wrong?
Sources
- https://developer.mozilla.org/en-US/docs/Web/API/Element/focusin_event
- https://caniuse.com/focusin-focusout-events
- https://w3c.github.io/uievents/#event-type-focus
From caniuse.com:
The
focusin
andfocusout
events fire just before the element gains or loses focus, and they bubble. By contrast, thefocus
andblur
events fire after the focus has shifted, and don’t bubble.
From mozilla.org/…/focusin_event and …/focus_event:
The
focusin
event fires when an element is about to receive focus.
Thefocus event
fires when an element has received focus.
From w3c.github.io:
(Regarding
focusin
) This event type is similar tofocus
, but is dispatched before focus is shifted
(Regardingfocus
) This event type is similar tofocusin
, but is dispatched after focus is shifted