586

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

我在想我们可以使用某种条件来阻止这种行为。例如,如果我们在鼠标移出时测试任何输入是否有焦点,我们可以阻止边框消失。AFAIK,jQuery 中没有:focus选择器,所以我不知道如何做到这一点。有任何想法吗?

4

15 回答 15

974

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)添加测试是为了过滤掉像身体这样的误报。这样,我们确保过滤掉除表单控件和超链接之外的所有元素。

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

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 );
于 2010-04-21T16:04:18.013 回答
47

CSS:

.focus {
    border-color:red;
}

查询:

  $(document).ready(function() {

    $('input').blur(function() {
        $('input').removeClass("focus");
      })
      .focus(function() {
        $(this).addClass("focus")
      });
  });
于 2009-06-08T21:41:38.043 回答
22

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

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

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

(取自Ben Alman这个要点。)

于 2011-03-22T12:58:29.440 回答
17

2015 年 4 月更新

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

取而代之的是该.on方法。

他们的文档对于解释它是如何工作的非常有用;

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

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

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

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

于 2015-04-07T15:27:55.557 回答
2

我不完全确定你在追求什么,但这听起来可以通过将输入元素(或 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;
        });
});
于 2009-06-08T21:37:31.763 回答
1

你有没有想过用mouseOvermouseOut来模拟这个。还要查看mouseEntermouseLeave

于 2009-06-08T21:29:06.443 回答
1

使用类来标记元素状态的替代方法是内部数据存储功能

PS:您可以使用该data()功能存储布尔值和您想要的任何内容。这不仅仅是关于字符串:)

$("...").mouseover(function ()
{
    // store state on element
}).mouseout(function ()
{
    // remove stored state on element
});

然后它只是访问元素状态的问题。

于 2009-06-09T11:30:07.507 回答
1

如果有人关心现在有更好的方法来捕捉焦点,$(foo).focus(...)

http://api.jquery.com/focus/

于 2014-10-30T03:51:46.553 回答
0

跟踪两种状态(悬停,聚焦)作为真/假标志,并且每当其中一个更改时,运行一个函数,如果两者都为假,则删除边框,否则显示边框。

所以:onfocus 设置focused = true,onblur设置focused = false。onmouseover 设置悬停 = true,onmouseout 设置悬停 = false。在这些事件中的每一个之后运行一个添加/删除边框的函数。

于 2009-06-08T21:35:40.020 回答
0

据我所知,你不能询问浏览器屏幕上的任何输入是否有焦点,你必须设置某种焦点跟踪。

我通常有一个名为“noFocus”的变量并将其设置为 true。然后我将焦点事件添加到使 noFocus 为假的所有输入。然后我向所有将 noFocus 设置回 true 的输入添加一个模糊事件。

我有一个 MooTools 类可以很容易地处理这个问题,我相信你可以创建一个 jquery 插件来做同样的事情。

创建完成后,您可以在进行任何边界交换之前检查 noFocus。

于 2009-06-08T21:36:40.283 回答
0

没有:focus,但有:selected http://docs.jquery.com/Selectors/selected

但是,如果您想根据所选内容更改事物的外观,您可能应该使用模糊事件。

http://docs.jquery.com/Events/blur

于 2009-06-08T21:38:14.243 回答
0

我最终要做的是创建一个名为 .elementhasfocus 的任意类,该类在 jQuery focus() 函数中添加和删除。当鼠标悬停时 hover() 函数运行时,它会检查 .elementhasfocus:

if(!$("#quotebox").is(".boxhasfocus")) $(this).removeClass("box_border");

因此,如果它没有该类(阅读:div 中没有元素具有焦点),则删除边框。否则,什么都不会发生。

于 2009-06-08T21:41:26.060 回答
0

有一个插件可以检查元素是否被聚焦: http: //plugins.jquery.com/project/focused

$('input').each(function(){
   if ($(this) == $.focused()) {
      $(this).addClass('focused');
   }
})
于 2009-11-12T09:05:16.220 回答
0

我将 .live("focus") 事件设置为 select() (突出显示)文本输入的内容,这样用户就不必在输入新值之前选择它。

$(formObj).select();

由于不同浏览器之间的怪癖,选择有时会被导致它的单击所取代,并且它会在将光标放在文本字段中之后立即取消选择内容(在 FF 中大部分工作正常,但在 IE 中失败)

我想我可以通过稍微延迟选择来解决这个问题......

setTimeout(function(){$(formObj).select();},200);

这工作正常,选择将持续存在,但出现了一个有趣的问题。如果您从一个字段切换到下一个字段,焦点将在选择发生之前切换到下一个字段。由于 select 窃取焦点,焦点将返回并触发新的“焦点”事件。这最终导致一连串的输入选择在整个屏幕上跳舞。

一个可行的解决方案是在执行 select() 之前检查该字段是否仍然具有焦点,但如前所述,没有简单的检查方法......我最终只是放弃了整个自动突出显示,而不是转动应该是什么一个 jQuery select() 调用到一个带有子程序的巨大函数......

于 2011-09-08T19:56:19.683 回答
-2

简单的

 <input type="text" /> 



 <script>
     $("input").focusin(function() {

    alert("I am in Focus");

     });
 </script>
于 2012-03-16T07:28:22.680 回答