表单元素上的jQuery focusout事件即使在单击子元素时也会被触发

jQuery focusout event on form element is triggered even when child element is clicked

本文关键字:元素 单击 jQuery focusout 事件 表单      更新时间:2023-09-26

当用户不关注整个表单元素时,我想触发focusout。但当用户点击表单的任何内部元素时,它不应该触发,比如本例中的文本字段或按钮。但是,即使事件绑定到整个表单,它也会被触发。如何解决此问题?

http://jsfiddle.net/exutahfa/

HTML:

<form>
    <input type="text" />
    <button type="button">Click Me</button>
</form>

jQuery:

$('form').on('focusout', function() {
   alert('focus out');    
});

之所以会发生这种情况,是因为您实际上并没有关注表单,而是关注其子元素之一(在您的情况下是输入或按钮)。focusout(或模糊)事件将冒泡到form,但不是由它直接触发的。

可能想要:

  1. 在表单输入上捕获blur事件
  2. 查看同一表单的另一子元素是否收到焦点
$('form').on('focusout', function () {
    var $elem = $(this);
    // let the browser set focus on the newly clicked elem before check
    setTimeout(function () {
        if (!$elem.find(':focus').length) {
            alert('focus out');
        }
    }, 0);
});

JSFiddle上的工作示例。

看看这个表单是如何在链接的fiddle中没有得到任何关注的:如果它得到了关注,它会用红色边框突出显示(参见CSS定义)。

focusout事件不是这样工作的。

来自jQuery文档:

当传递参数时,此方法是.on("focusout",处理程序)的快捷方式,当不传递参数时是.trick("foocuout")的快捷方法。

当某个元素或其中的任何元素失去焦点时,focusout事件被发送到该元素。这与模糊事件的不同之处在于,它支持检测子元素上的焦点丢失(换句话说,它支持事件冒泡)

此事件可能会与focusin事件一起使用。

小提琴中的事件被激发的原因是它检测到子元素的焦点丢失。一般来说,我认为form元素本身甚至不能有焦点,所以调用$('form').blur(function() { alert('focus lost') });也不会实现您希望它做的事情。但是,您可以在表单的内部元素上使用.blur(),如果您针对特定的元素并希望它们都做不同的事情,则可以使其以相同的方式工作。

目前,一种形式不可能有焦点,但它的后代可以,这就是为什么你会遇到这个问题。如果您试图调用一个在选中表单时更改表单的事件,那么当用户第一次关注表单中的某个输入字段时,请尝试向其中添加一个类,然后当他们单击页面上不在表单中的任何其他内容时,从表单中删除该类。

您必须将焦点专门应用于您希望它处理的元素,而不是所有的表单。示例:

HTML:

<form>
    <input id="focus" type="text" />  
    <button type="button">Click Me</button>
</form>

JavaScript:

$( "#focus" ).on('focusout', function() {
   alert('focus out');    
});