7

编辑:请参阅下面我自己的答案: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 不会将焦点放在外部,如果外部先前有焦点,则单击子会导致外部模糊,这对我想做的事情来说是一种痛苦。

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")
});
4

5 回答 5

9

拦截事件和使用 JS 设置焦点最终导致更多问题。

我最终发现使用像 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")
});
于 2014-09-20T22:00:06.697 回答
5

您是否尝试添加:

$inner.click(function() {
  $div.focus();
});

并防止在焦点使用后外部 div 模糊e.stopPropagation()

更新:由于click事件在blur我使用Mousedown事件之后触发,因为它在blur.

PS:keydown如果您还想捕捉键盘触发的模糊,请不要忘记处理键盘事件。

http://jsfiddle.net/ouadie/x4nAX/

于 2013-08-15T19:23:11.257 回答
0

在 IE 中单击 tabindex=0 的元素将导致该元素获得不可见的焦点。获得可见焦点的方法是在元素还没有不可见焦点时以编程方式调用 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')
})

如果child是inline或者是没有设置宽度的block,效果和直接点击parent是一样的。但是,如果子级是内联块或设置了宽度的块,并且父级已经具有焦点,则父级将在执行 mousedown 处理程序后立即 blur()。我们有三种不同的方式进行,有不同的权衡。

一种选择是仅使用 preventDefault() 来抑制模糊;这种方法的优点是 blur() 永远不会触发, focus() 不会冗余触发,这允许我们在 focus 和 blur 处理程序中编写简单的逻辑;这种方法的缺点是它禁用了文本选择:

$('#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')
})
于 2014-04-18T18:36:28.530 回答
0

root成为你的#testdiv

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 年以来就没有被清理过。当人们谈论“IE 11 是现代浏览器”或“IE 11 关心标准”时,我笑了。

于 2014-05-15T13:50:50.130 回答
-1

这个问题很老,但我刚刚遇到了这个问题,以下解决方案在 IE11 中有效,并且比任何其他解决方案都简单得多:

.iesux {
     border:1px solid #000;
     display:block;
     padding:8px;
     background-color:#FFF;
     cursor:default;
     width:200px;
     pointer-events: none;
}

不幸的是,IE<11 不支持它,但如果你能摆脱它,这是迄今为止最简单的。

http://jsfiddle.net/anXM3/22/

于 2015-11-03T10:53:08.563 回答