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
edit 1
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?
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
edit 1
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?
Share Improve this question edited Mar 6, 2012 at 5:08 bernie asked Mar 6, 2012 at 4:38 berniebernie 10.4k7 gold badges66 silver badges99 bronze badges 6- Have you tried changing $('form').on("focus", function(event){ to, $('form').on("focus", "input", function(event){ ? – Ohgodwhy Commented Mar 6, 2012 at 4:51
- try adding a native javascript event handler and see what that does – charlietfl Commented Mar 6, 2012 at 4:58
- @Ohgodwhy: Isn't that the same thing I posted in the 3rd code block? – bernie Commented Mar 6, 2012 at 5:01
- 2 jQuery uses the WC3 valid call of 'focusin', which #1 does not allow for bubbling, and #2 does not allow for anything other than the following elements -> LABEL, INPUT, SELECT, TEXTAREA, and BUTTON. – Ohgodwhy Commented Mar 6, 2012 at 5:03
- 3 You can use the jQuery method of focusin, but you cannot use the focus method as it does not support bubbling. – Ohgodwhy Commented Mar 6, 2012 at 5:10
3 Answers
Reset to default 4As 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 ments).
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/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.
Jquery has a cross browser function which takes care of focus delegations.
Chrome,safari and opera support an event called "DOMFocusIn" which actually delegates.
IE supports an event "focusin" for delegating focus.
Firefox supports "focus" only on capturing phase and not bubbling phase.
jQuery made a cross browser event which is "focus" which actually delegates.
I hope this answers all your doubts.