使用 jQuery 测试输入是不是有焦点

Posted

技术标签:

【中文标题】使用 jQuery 测试输入是不是有焦点【英文标题】:Using jQuery to test if an input has focus使用 jQuery 测试输入是否有焦点 【发布时间】:2010-11-01 07:29:57 【问题描述】:

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

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

【问题讨论】:

你能试着把它归结为几句话需要什么,我发生了什么? 我认为您需要考虑捕捉焦点和模糊事件(docs.jquery.com/Events/focus 和 docs.jquery.com/Events/blur) 我在相关问题"Is there a ‘has focus’ in javascript (or jQuery)?" 上发布了答案。我增强了 [gnarf 引用的 cletus 方法](#2684561)。 【参考方案1】:

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

【讨论】:

这基本上就是我对 jQuery 的悬停所做的。您提供两个函数,一个用于鼠标输入,一个用于鼠标移出。【参考方案2】:

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

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

【讨论】:

【参考方案3】:

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

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

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

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

【讨论】:

【参考方案4】:

我不完全确定您在追求什么,但这听起来可以通过将输入元素(或 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;
        );
);

【讨论】:

这是我最终要做的,但我使用了任意 CSS 类而不是全局 javascript 变量。 我使用了这个的变体。不需要新的 jQuery 插件。这让我成为一个快乐的露营者!【参考方案5】:

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

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

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

【讨论】:

【参考方案6】:

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

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

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

【讨论】:

【参考方案7】:

CSS:

.focus 
    border-color:red;

JQuery:

  $(document).ready(function() 

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

【讨论】:

【参考方案8】:

使用类来标记元素状态的替代方法是内部data store functionality。

P.S.:你可以使用 data() 函数存储布尔值和任何你想要的东西。这不仅仅是关于字符串:)

$("...").mouseover(function ()

    // store state on element
).mouseout(function ()

    // remove stored state on element
);

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

【讨论】:

【参考方案9】:

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

$('input').each(function()
   if ($(this) == $.focused()) 
      $(this).addClass('focused');
   
)

【讨论】:

既然可以使用核心 jquery,为什么还要使用插件? 你是对的。但我在 2 年前不知道这个问题的解决方案。【参考方案10】:

jQuery 1.6+

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

jQuery 1.5 及以下

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

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

引自 Mathias Bynens here:

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

您正在定义一个新的选择器。见Plugins/Authoring。然后你可以这样做:

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 );

【讨论】:

这可能会导致误报。请参阅***.com/questions/967096/… 了解更多信息(感谢 Ben Alman 和 Diego Perini)。 @Mathias Bynens - 感谢您的更新(非常欢迎您编辑此社区 wiki 答案顺便说一句!) 当您需要它同时使用 1.5- 和 1.6 时怎么办?我不想覆盖 jQuery 自己的焦点选择器。 if (!jQuery.expr[':'].focus) /* gist from Ben Alman */ 之类的东西? @betamos - 完全正确...我将在答案中添加一些内容以反映这一点。 @Alex - 请在 jsFiddle 上提供一个简化的测试用例来显示问题,因为据我所知,没有理由这 不应该 在“动态”上工作元素。我称之为恶作剧......【参考方案11】:

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

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

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

(取自this gistBen Alman。)

【讨论】:

【参考方案12】:

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

$(formObj).select();

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

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

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

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

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

【讨论】:

【参考方案13】:

简单

 <input type="text" /> 



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

    alert("I am in Focus");

     );
 </script>

【讨论】:

这并不能告诉您当前焦点所在的元素。当新元素获得焦点时调用它。所以如果一个元素已经有了焦点,并且你想知道'this'是否是那个,那么这段代码是没有用的。【参考方案14】:

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

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

【讨论】:

【参考方案15】:

2015 年 4 月更新

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

现在引入了.on 方法来代替它。

他们的documentation 在解释其工作原理方面非常有用;

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

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

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

这非常健壮,甚至还允许您使用 TAB 键。

【讨论】:

非常好的解决方案,谢谢。将on("focusout", 用于相反的功能

以上是关于使用 jQuery 测试输入是不是有焦点的主要内容,如果未能解决你的问题,请参考以下文章

使用 Google Accessibility Developer Tools 的 jQuery UI Datepicker 焦点问题

如何测试元素是不是有焦点[重复]

JQuery下focus()无法自动获取焦点的处理方法 jquery如何使文本框获得焦点

如何使用 Jquery 使用户从确认框中的输入框中取消焦点?

无法使用 jQuery 传递焦点下一个输入

Jquery使用Id获取焦点和失去焦点