With the following html structure:
<div>
<form><span><input></span></form>
</div>
<p>
and the following jquery code:
$('form').on("focus", function(event) {
$("p").append("focus no delegation<br>");
})
Why doesn't the focus event ever reach my event handler? Binding the event with a selector parameter works fine:
$('form').on("focus", "input", function(event) {
$("p").append("focus delegation<br>");
})
Event the next snippet works so the focus event does in fact bubble...
$('form').on("focus", "span", function(event) {
$("p").append("focus delegation<br>");
})
Both forms work with click and change events:
$('form').on("click", function(event) {
$("p").append("click no delegation<br>");
})
$('form').on("click", "input", function(event) {
$("p").append("click delegation<br>");
})
The only note I found about the focus event's bubbling is relative to older jQuery versions which I don't use. See it in action here
Well this is confusing... According to jQuery's focus doc:
The focus event does not bubble in Internet Explorer. Therefore, scripts that rely on event delegation with the focus event will not work consistently across browsers. As of version 1.4.2, however, jQuery works around this limitation by mapping focus to the focusin event in its event delegation methods, .live() and .delegate().
And according to jQuery's focusin doc:
The focusin event is sent to an element when it, or any element inside of it, gains focus. This is distinct from the focus event in that it supports detecting the focus event on parent elements (in other words, it supports event bubbling).
Is it too late for me or does one contradict the other?
The focus event fires when an element has received focus. The event does not bubble, but the related focusin event that follows does bubble. The opposite of focus is the blur event, which fires when the element has lost focus. The focus event is not cancelable.
Event bubbling on( 'click', function( event ) { event. preventDefault(); console. log( this ); }); It binds a click handler to all elements in a document (something you should never do in real code), as well as to the document and window .
The focusout event fires when an element has lost focus, after the blur event. The two events differ in that focusout bubbles, while blur does not. The opposite of focusout is the focusin event, which fires when the element has received focus.
The focusin event fires when an element has received focus, after the focus event. The two events differ in that focusin bubbles, while focus does not. The opposite of focusin is the focusout event, which fires when the element has lost focus.
As Ohgodwhy pointed out, using focusin instead of focus does work.
However, I can't understand how the following code can work if the "focus" event does not bubble:
$('form').on("focus", "span", function(event) {
$("p").append("focus delegation<br>");
})
If a span child of the form receives the "focus" event, it means that the event bubbled from the input to the span. Even this works!
$('div').on("focus", "form", function(event) {
$("p").append("focus delegation<br>");
})
So... using "focusin" does fix the problem, but I'm not fully satisfied by this workaround. If anybody has a better answer, I'll happily accept it.
Yes, it appears the jQuery docs are misleading. I believe the documentation on focus
neglected to mention that this was for the elements that aren't involved in user input (@Ohgodwhy listed them above in your question's comments).
I imagine it has something to do with the browser's need to trap the cursor in the input element that has focus
, so that it can accept input from the keyboard. In other words, if jQuery allowed it to bubble, then you would never be given the chance to type in the input field.
Either way you'll never get a form to accept a focus
event unless you first put a tabindex
on it: http://jsfiddle.net/qxLqP/ but if an input based field gets focus first, it will never bubble. By default, the form
element doesn't have a tabindex
, and you can't set focus to something that doesn't have a tabindex
.
I'd just accept @Ohgodwhy's solution of using focusin
and then go let the jQuery team know about their confusing documentation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With