【问题标题】:Focus and blur jQuery events not bubbling焦点和模糊 jQuery 事件不冒泡
【发布时间】:2012-03-06 04:38:18
【问题描述】:

具有以下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>");
})

事件下一个 sn-p 工作,所以焦点事件实际上会冒泡......

$('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 doc:

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

对我来说太晚了还是两者相矛盾?

【问题讨论】:

  • 你试过把 $('form').on("focus", function(event){ 改成, $('form').on("focus", "input", function (事件){ ?
  • 尝试添加原生 javascript 事件处理程序,看看会发生什么
  • @Ohgodwhy:这不是我在第三个代码块中发布的内容吗?
  • jQuery 使用 WC3 有效调用 'focusin',其中 #1 不允许冒泡,而 #2 不允许出现以下元素以外的任何内容 -> LABEL、INPUT、SELECT、TEXTAREA和按钮。
  • 可以使用jQuery的focusin方法,但不能使用focus方法,因为它不支持冒泡。

标签: javascript jquery event-handling


【解决方案1】:

正如 Ohgodwhy 所指出的,使用 focusin 代替 focus 确实有效。

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

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

如果表单的 span 子级接收到“focus”事件,则表示该事件从输入冒泡到 span。即使这样也行!

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

所以...使用“focusin”确实可以解决问题,但我对这种解决方法并不完全满意。如果有人有更好的答案,我很乐意接受。

【讨论】:

    【解决方案2】:

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

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

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

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

    【讨论】:

      【解决方案3】:

      Jquery 有一个跨浏览器功能,可以处理焦点委托。

      Chrome、safari 和 Opera 支持一个名为“DOMFocusIn”的事件,它实际上是委托的。

      IE 支持事件“focusin”来委派焦点。

      Firefox 仅支持在捕获阶段而不是冒泡阶段“聚焦”。

      jQuery 制作了一个跨浏览器事件,它实际上是委托的“焦点”。

      我希望这能解答你所有的疑惑。

      【讨论】:

      • 我不确定我是否理解您的回答。如果您尝试我在问题中发布的 jsfiddle(使用 IE 和 Firefox),focus 在没有授权的情况下不会在表单上触发。
      • 这并不能解释为什么在你的小提琴中这也会起作用: $('#container') .on('focus','label',function(e){...}) ;没有提到可聚焦元素...
      猜你喜欢
      • 1970-01-01
      • 2011-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-19
      • 2011-10-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多