EDIT: See my own answer below: https://stackoverflow.com/a/25953721/674863
Demo: http://jsfiddle.net/fergal_doyle/anXM3/1/
I have a div with tabindex=0, and a child div with a fixed width. When I click on the child div I expect the outer div to recieve focus. This works fine with Firefox and Chrome, and only works with Internet Explorer (7 to 10) when the child div has no width applied.
With a width, clicking the child (white) div does not give focus to the outer one, and if the outer one previously had focus, clicking the child causes the outer to blur, which is a pain for what I want to do.
HTML:
<div tabindex="0" id="test">
<div>Click</div>
</div>
CSS:
div {
border:1px solid #000;
padding:20px;
background-color:red;
}
div div {
padding:8px;
background-color:#FFF;
cursor:default;
width:200px;
}
JS:
var $div = $("#test"),
$inner = $("#test > div");
$div.on("blur", function (e) {
console.log("blur");
})
.on("focus", function (e) {
console.log("focus")
});
Have you tried to add :
and to prevent the outer div to blur after a focus use
e.stopPropagation()
UPDATE: Since the
click
event fires after theblur
I used theMousedown
event, because it fires beforeblur
.PS: Don't forget to handle keyboard events
keydown
if you want also to catch blurs fired by the keyboard.http://jsfiddle.net/ouadie/x4nAX/
This question is old, but I just came across this problem and the following solution works in IE11 and is much simpler than any other:
It's not supported in IE<11 unfortunately but if you can get away with that it's by far the easiest.
http://jsfiddle.net/anXM3/22/
Clicking on an element with tabindex=0 in IE will result in the element gaining invisible focus. The way to gain visible focus is by programmatically calling focus() while the element does not already have invisible focus. Since focus happens right after mousedown, this means we need:
If the child is inline or a block with no width set, the effect is the same as clicking directly on the parent. However, if the child is an inline-block or a block with a width set, and the parent already had focus, then the parent will blur() right after the mousedown handlers are executed. We have three different ways to proceed, with different tradeoffs.
One option is to merely suppress the blur with preventDefault(); the virtue of this approach is that blur() will never fire and focus() will not fire redundantly, which allows us to write straightforward logic in our focus and blur handlers; the vice of this approach is that it disables text selection:
If we don't want to disable text selection, another option is to focus on the parent from the child's mouseup handler; however, this way the parent will blur and then focus again, which prevents us from knowing when a focus or blur is "real" rather than merely a transient consequence of our focus-propagation logic:
The third option has the virtues of both of the above approaches, but is the most complicated logically:
Let
root
be your#test
divYou should use
event.stopPropagation()
in any click inroot
, that should not force focus event.This problem is one of the great amount of problems in any IE (5-11). You can see that IE's source code was not cleaned since 1999. I am laughing when people are talking about "IE 11 is a modern browser" or "IE 11 care about standards".
Intercepting events and using JS to set focus ended up causing more problems.
I eventually figured out that using "normal" tags like divs or spans makes IE behave incorrectly. But use something like
var
or any custom tag and IE starts to behave like a proper browser.See updated example: http://jsfiddle.net/fergal_doyle/anXM3/16/
HTML:
CSS:
JS: