聚焦和模糊jQuery事件而不是冒泡

时间:2012-03-06 04:38:19

标签: javascript jquery event-handling

使用以下html结构:

<div>
<form><span><input></span></form>
</div>
<p>

以及以下jquery代码:

$('form').on("focus", function(event) {
    $("p").append("focus no delegation<br>");
})

为什么焦点事件不会到达我的事件处理程序?使用选择器参数绑定事件可以正常工作:

$('form').on("focus", "input", function(event) {
    $("p").append("focus delegation<br>");
})

事件下一个片段有效,因此焦点事件确实会冒泡......

$('form').on("focus", "span", function(event) {
    $("p").append("focus delegation<br>");
})

这两种表单都适用于点击和更改事件:

$('form').on("click", function(event) {
    $("p").append("click no delegation<br>");
})
$('form').on("click", "input", function(event) {
    $("p").append("click delegation<br>");
})

我发现关于焦点事件冒泡的唯一注意事项是相对于我不使用的旧jQuery版本。查看行动here

编辑1

这很令人困惑......根据jQuery的重点文档:

  

焦点事件不会在Internet Explorer中冒泡。因此,依赖于焦点事件的事件委派的脚本将无法跨浏览器一致地工作。但是,从版本1.4.2开始,jQuery通过将焦点映射到其事件委托方法.live()和.delegate()中的focusin事件来解决此限制。

根据jQuery的焦点文档:

  

当focusin事件或其中的任何元素获得焦点时,focusin事件将被发送到该元素。这与焦点事件的区别在于它支持检测父元素上的焦点事件(换句话说,它支持事件冒泡)。

对我来说为时已晚还是与另一方相矛盾?

3 个答案:

答案 0 :(得分:3)

正如Ohgodwhy指出的那样,使用focusin代替焦点确实有用。

但是,如果“焦点”事件没有冒泡,我无法理解以下代码如何工作:

$('form').on("focus", "span", function(event) {
    $("p").append("focus delegation<br>");
})

如果表单的span子节点收到“焦点”事件,则表示事件从输入冒泡到span。即便如此!

$('div').on("focus", "form", function(event) {
    $("p").append("focus delegation<br>");
})

所以...使用“focusin”确实解决了这个问题,但我对此解决方法并不完全满意。如果有人有更好的答案,我会很高兴地接受它。

答案 1 :(得分:3)

是的,似乎jQuery文档具有误导性。我相信focus上的文档忽略了这是针对那些不涉及用户输入的元素(@Ohgodwhy在你的问题评论中将它们列在上面)。

我想这与浏览器需要将光标捕获到具有focus的输入元素有关,因此它可以接受来自键盘的输入。换句话说,如果jQuery允许它冒泡,那么你永远不会有机会输入输入字段。

无论哪种方式,您都永远不会收到表单来接受focus事件,除非您先在其上添加tabindexhttp://jsfiddle.net/qxLqP/但如果基于输入的字段首先获得焦点,则永远不会冒泡。默认情况下,form元素没有tabindex,您无法将焦点设置为没有tabindex的内容。

我接受@ Ohgodwhy使用focusin的解决方案,然后让jQuery团队了解他们令人困惑的文档。

答案 2 :(得分:0)

Jquery有一个跨浏览器功能,负责焦点授权。

Chrome,safari和opera支持名为“DOMFocusIn”的事件,该事件实际上是委派的。

IE支持用于委派焦点的事件“focusin”。

Firefox仅支持“关注”捕获阶段而不是冒泡阶段。

jQuery创建了一个跨浏览器事件,它实际上代表了“焦点”。

我希望这能解决你所有的疑虑。