使用 jQuery 测试输入是否具有焦点

IT技术 javascript jquery jquery-events jquery-on
2021-01-19 23:17:12

在我正在构建的站点的首页上,有几个<div>使用 CSS:hover伪类在鼠标悬停在它们上方时添加边框。其中一个<div>s 包含 a <form>,如果其中的输入具有焦点,则使用 jQuery 将保留边框。除了 IE6 不支持s:hover以外<a>任何元素,这完美地工作所以,对于这个浏览器,我们只使用 jQuery 来模拟 CSS:hover使用该$(#element).hover()方法。唯一的问题是,现在 jQuery 处理表单focus() hover(),当输入具有焦点时,用户将鼠标移入移出,边框消失。

我在想我们可以使用某种条件来阻止这种行为。例如,如果我们测试鼠标移出是否有任何输入具有焦点,我们可以阻止边框消失。AFAIK,:focusjQuery 中没有选择器,所以我不确定如何实现。有任何想法吗?

6个回答

jQuery 1.6+

jQuery 添加了一个:focus选择器,所以我们不再需要自己添加它。只需使用$("..").is(":focus")

jQuery 1.5 及以下

编辑:随着时代的变化,我们找到了更好的测试焦点方法,新的最爱是Ben Alman 的这个要点

jQuery.expr[':'].focus = function( elem ) {
  return elem === document.activeElement && ( elem.type || elem.href );
};

引自 Mathias Bynens在这里

请注意,(elem.type || elem.href)添加测试是为了过滤掉像 body 这样的误报。这样,我们确保过滤掉除表单控件和超链接之外的所有元素。

您正在定义一个新的选择器。请参阅插件/创作然后你可以这样做:

if ($("...").is(":focus")) {
  ...
}

或者:

$("input:focus").doStuff();

任何 jQuery

如果你只想找出哪个元素有焦点,你可以使用

$(document.activeElement)

如果您不确定版本是否为 1.6 或更低,您可以添加:focus缺少选择器:

(function ( $ ) {
    var filters = $.expr[":"];
    if ( !filters.focus ) { 
        filters.focus = function( elem ) {
           return elem === document.activeElement && ( elem.type || elem.href );
        };
    }
})( jQuery );
这可能会导致误报。请参阅stackoverflow.com/questions/967096/...了解更多信息(感谢 Ben Alman 和 Diego Perini)。
2021-03-12 23:17:12
@Mathias Bynens - 感谢您的更新(顺便说一句,非常欢迎您编辑此社区 wiki 答案!)
2021-03-19 23:17:12
@betamos - 完全正确......我会在答案中添加一些内容来反映这一点。
2021-03-24 23:17:12
@Alex - 请在 jsFiddle 上提供一个显示问题的简化测试用例,因为据我所知,没有理由这不适用于“动态”元素。我称之为恶作剧...
2021-04-03 23:17:12
当您需要它同时使用 1.5 和 1.6 时呢?我不想覆盖 jQuery 自己的焦点选择器。if (!jQuery.expr[':'].focus) { /* gist from Ben Alman */ }什么?
2021-04-05 23:17:12

CSS:

.focus {
    border-color:red;
}

查询:

  $(document).ready(function() {

    $('input').blur(function() {
        $('input').removeClass("focus");
      })
      .focus(function() {
        $(this).addClass("focus")
      });
  });

这是一个比目前接受的答案更可靠的答案:

jQuery.expr[':'].focus = function(elem) {
  return elem === document.activeElement && (elem.type || elem.href);
};

请注意,(elem.type || elem.href)添加测试是为了过滤掉像body. 这样,我们确保过滤掉除表单控件和超链接之外的所有元素。

(从·阿尔曼( Ben Alman ) 的这篇要点中摘取。)

2015 年 4 月更新

由于这个问题已经存在了一段时间,并且一些新的约定开始发挥作用,我觉得我应该提到该.live方法已被贬值。

取而代之的是,.on现在已经引入了该方法。

他们的文档对于解释它的工作原理非常有用;

.on() 方法将事件处理程序附加到 jQuery 对象中当前选定的一组元素。从 jQuery 1.7 开始, .on() 方法提供了附加事件处理程序所需的所有功能。有关从旧 jQuery 事件方法转换的帮助,请参阅 .bind()、.delegate() 和 .live()。

因此,为了让您针对“输入焦点”事件,您可以在脚本中使用它。就像是:

$('input').on("focus", function(){
   //do some stuff
});

这非常强大,甚至还允许您使用 TAB 键。

很好的解决方案,谢谢。使用on("focusout",了相反的功能
2021-03-23 23:17:12

我不完全确定你在追求什么,但这听起来可以通过将输入元素(或 div?)的状态存储为变量来实现:

$('div').each(function(){

    var childInputHasFocus = false;

    $(this).hover(function(){
        if (childInputHasFocus) {
            // do something
        } else { }
    }, function() {
        if (childInputHasFocus) {
            // do something
        } else { }
    });

    $('input', this)
        .focus(function(){
            childInputHasFocus = true;
        })
        .blur(function(){
            childInputHasFocus = false;
        });
});
我使用了这个的变体。不需要新的 jQuery 插件。这让我成为一个快乐的露营者!
2021-04-02 23:17:12
这就是我最终要做的,但我使用了一个任意的 CSS 类,而不是一个全局的 javascript 变量。
2021-04-07 23:17:12