使用以下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
这很令人困惑......根据jQuery的重点文档:
焦点事件不会在Internet Explorer中冒泡。因此,依赖于焦点事件的事件委派的脚本将无法跨浏览器一致地工作。但是,从版本1.4.2开始,jQuery通过将焦点映射到其事件委托方法.live()和.delegate()中的focusin事件来解决此限制。
根据jQuery的焦点文档:
当focusin事件或其中的任何元素获得焦点时,focusin事件将被发送到该元素。这与焦点事件的区别在于它支持检测父元素上的焦点事件(换句话说,它支持事件冒泡)。
对我来说为时已晚还是与另一方相矛盾?
答案 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
事件,除非您先在其上添加tabindex
:http://jsfiddle.net/qxLqP/但如果基于输入的字段首先获得焦点,则永远不会冒泡。默认情况下,form
元素没有tabindex
,您无法将焦点设置为没有tabindex
的内容。
我接受@ Ohgodwhy使用focusin
的解决方案,然后让jQuery团队了解他们令人困惑的文档。
答案 2 :(得分:0)
Jquery有一个跨浏览器功能,负责焦点授权。
Chrome,safari和opera支持名为“DOMFocusIn”的事件,该事件实际上是委派的。
IE支持用于委派焦点的事件“focusin”。
Firefox仅支持“关注”捕获阶段而不是冒泡阶段。
jQuery创建了一个跨浏览器事件,它实际上代表了“焦点”。
我希望这能解决你所有的疑虑。