具有以下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版本。点击此处查看行动
编辑1
这太令人困惑了。。。根据jQuery的焦点文档:
焦点事件不会在Internet Explorer中冒泡。因此,依赖于焦点事件的事件委派的脚本将无法在浏览器之间一致工作。然而,从1.4.2版本开始,jQuery通过在其事件委托方法.live()和.delete().中将焦点映射到focusin事件来绕过这一限制
根据jQuery的focusin文档:
当某个元素或其内部的任何元素获得焦点时,focusin事件被发送到该元素。这与焦点事件的不同之处在于,它支持检测父元素上的焦点事件(换句话说,它支持事件冒泡)。
对我来说太晚了吗?还是两者矛盾?
正如Ohgodh为什么所指出的,使用focusin而不是focus确实有效。
然而,如果"焦点"事件没有冒泡,我无法理解以下代码是如何工作的:
$('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"确实解决了这个问题,但我对这个解决方法并不完全满意。如果有人有更好的答案,我很乐意接受。
是的,jQuery文档似乎具有误导性。我相信focus
上的文档忽略了这是针对用户输入中不涉及的元素的(@Ohgodh为什么在您的问题评论中列出了它们)。
我想这与浏览器需要将光标捕获在具有focus
的输入元素中有关,这样它就可以接受来自键盘的输入。换句话说,如果jQuery允许它冒泡,那么您将永远不会有机会在输入字段中键入。
无论哪种方式,除非您首先在表格上填写tabindex
,否则您永远不会获得接受focus
事件的表格:http://jsfiddle.net/qxLqP/但如果一个基于输入的字段首先得到关注,它就永远不会冒泡。默认情况下,form
元素没有tabindex
,并且不能将焦点设置为没有tabindex
的元素。
我只接受@Ohgodh为什么使用focusin
的解决方案,然后让jQuery团队了解他们令人困惑的文档。
Chrome、safari和opera支持一个名为"DOMFocusIn"的活动,该活动实际上是代表。
IE支持用于委派焦点的事件"focusin"。
Firefox只支持"关注"捕获阶段,而不支持冒泡阶段。
jQuery制作了一个跨浏览器事件,它是"焦点",实际上是委托。
我希望这能回答你所有的疑虑。