【问题标题】: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 选择器,所以我不确定如何实现这一点。有什么想法吗?

【问题讨论】:

标签: javascript jquery jquery-events jquery-on


【解决方案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 );
              

              【讨论】:

              • 这可能会导致误报。请参阅stackoverflow.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", 用于相反的功能
                    猜你喜欢
                    • 1970-01-01
                    • 2017-12-17
                    • 2017-03-18
                    • 1970-01-01
                    • 2019-04-02
                    • 1970-01-01
                    • 2010-09-26
                    • 1970-01-01
                    相关资源
                    最近更新 更多