编辑: 请参阅下面的我自己的答案:https://stackoverflow.com/a/25953721/674863
演示: http://jsfiddle.net/fergal_doyle/anXM3/1/
我有一个tabindex = 0的div和一个固定宽度的子div。当我点击子div时,我希望外部div能够获得焦点。这适用于Firefox和Chrome,并且仅当子div没有应用宽度时才适用于Internet Explorer(7到10)。
使用宽度,单击子(白色)div不会将焦点放在外面的div上,如果外面的那个以前有焦点,单击该子项会导致外部模糊,这对我想要的内容很痛苦做。
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")
});
答案 0 :(得分:7)
拦截事件并使用JS设置焦点最终导致更多问题。
我最终发现使用&#34;正常&#34;像div或spans这样的标签会让IE表现不正常。但是使用像var
或任何自定义标记这样的东西,IE开始表现得像一个合适的浏览器。
请参阅更新示例:http://jsfiddle.net/fergal_doyle/anXM3/16/
HTML:
<div tabindex="0" id="test">
<var class="iesux">Works</var>
<foo class="iesux">Works</foo>
<div class="iesux">Doesn't work in IE</div>
<span class="iesux">Doesn't work in IE</span>
</div>
CSS:
div {
border:1px solid #000;
padding:20px;
background-color:red;
}
.iesux {
border:1px solid #000;
display:block;
padding:8px;
background-color:#FFF;
cursor:default;
width:200px;
}
JS:
document.createElement("foo");
var $div = $("#test");
$div.on("blur", function (e) {
console.log("blur");
})
.on("focus", function (e) {
console.log("focus")
});
答案 1 :(得分:5)
您是否尝试添加:
$inner.click(function() {
$div.focus();
});
并在焦点使用e.stopPropagation()
更新:由于click
事件在blur
我使用了Mousedown
事件后触发,因为它会在blur
之前触发。
PS:如果您还希望捕捉键盘触发的模糊,请不要忘记处理键盘事件keydown
。
答案 2 :(得分:0)
在IE中单击tabindex = 0的元素将导致元素获得不可见焦点。获得可见焦点的方法是通过以编程方式调用focus(),而元素尚未具有不可见焦点。由于焦点发生在mousedown之后,这意味着我们需要:
$('#parent').mousedown(function(e){
var parent = $(e.currentTarget)
if (!parent.is(':focus')) {
parent.focus()
}
}).focus(function(e){
console.log('focused')
}).blur(function(e){
console.log('blurred')
})
如果子项是内联的或没有设置宽度的块,则效果与直接单击父项时的效果相同。但是,如果子项是内联块或具有宽度设置的块,并且父项已经具有焦点,则父项将在执行mousedown处理程序后立即模糊()。我们有三种不同的方式可以进行,并有不同的权衡。
一种选择是仅使用preventDefault()来抑制模糊;这种方法的优点是blur()永远不会激发,而focus()不会冗余地激发,这使我们能够在焦点和模糊处理程序中编写直接的逻辑;这种方法的缺点是它禁用了文本选择:
$('#child').mousedown(function(e){
e.preventDefault()
})
$('#parent').mousedown(function(e){
var parent = $(e.currentTarget)
if (!parent.is(':focus')) {
parent.focus()
}
}).focus(function(e){
console.log('focused')
}).blur(function(e){
console.log('blurred')
})
如果我们不想禁用文本选择,另一个选项是关注子项的mouseup处理程序中的父项;然而,这样父母会模糊然后再次聚焦,这使我们无法知道焦点或模糊何时是“真实的”而不仅仅是我们的焦点传播逻辑的瞬态结果:
$('#child').mouseup(function(e){
$(e.currentTarget).closest('[tabindex]').focus()
})
$('#parent').mousedown(function(e){
var parent = $(e.currentTarget)
if (!parent.is(':focus')) {
parent.focus()
}
}).focus(function(e){
console.log('focused')
}).blur(function(e){
console.log('blurred')
})
第三种选择具有上述两种方法的优点,但逻辑上最复杂:
$('#parent').mousedown(function(e){
var parent = $(e.currentTarget)
var parentWasClicked = parent.is(e.target)
var parentHasFocus = parent.is(':focus')
if (parentWasClicked && !parentHasFocus) {
parent.focus()
} else if (parentHasFocus && !parentWasClicked) {
window.ignoreFocusChanges = true
}
})
.mouseup(function(e){
var parent = $(e.currentTarget)
if (!parent.is(':focus')) {
parent.focus()
}
})
.blur(function(e){
if (window.ignoreFocusChanges) {
return
}
console.log('blurred')
})
.focus(function(e){
if (window.ignoreFocusChanges) {
window.ignoreFocusChanges = false
return
}
console.log('focused')
})
答案 3 :(得分:0)
让root
成为您的#test
div
function prevent_blur_in_subtree = function (event) {
if (event.originalEvent && event.target != root.get(0) && $(event.target).closest(root).size() == 1) {
$(window).one("mousedown", prevent_blur_in_subtree);
event.stopPropagation();
event.preventDefault();
return false;
}
}
root.bind("click", function () {
if (!$(this).is(":focus")) {
$(this).trigger("focus");
}
})
.bind("focus", function () {
$(window).one("mousedown", prevent_blur_in_subtree);
});
您应该在event.stopPropagation()
中的任何点击中使用root
,这不应强制焦点事件。
这个问题是任何IE(5-11)中的大量问题之一。你可以看到IE的源代码自1999年以来就没有被清理过。我在笑的时候人们在谈论&#34; IE 11是一个现代浏览器&#34;或者&#34; IE 11关心标准&#34;。
答案 4 :(得分:-1)
这个问题很老,但我刚遇到这个问题,以下解决方案在IE11中运行,并且比其他任何一个简单得多:
.iesux {
border:1px solid #000;
display:block;
padding:8px;
background-color:#FFF;
cursor:default;
width:200px;
pointer-events: none;
}
不幸的是IE&lt; 11不支持它,但是如果你可以侥幸成功那么它是迄今为止最简单的。