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

时间:2022-12-06 15:58:17

On the front page of a site I am building, several <div>s use the CSS :hover pseudo-class to add a border when the mouse is over them. One of the <div>s contains a <form> which, using jQuery, will keep the border if an input within it has focus. This works perfectly except that IE6 does not support :hover on any elements other than <a>s. So, for this browser only we are using jQuery to mimic CSS :hover using the $(#element).hover() method. The only problem is, now that jQuery handles both the form focus() and hover(), when an input has focus then the user moves the mouse in and out, the border goes away.

在我正在构建的站点的首页上,几个

s使用CSS:hover伪类在鼠标位于它们上方时添加边框。其中一个

I was thinking we could use some kind of conditional to stop this behavior. For instance, if we tested on mouse out if any of the inputs had focus, we could stop the border from going away. AFAIK, there is no :focus selector in jQuery, so I'm not sure how to make this happen. Any ideas?

我想我们可以用某种条件来阻止这种行为。例如,如果我们在鼠标上进行测试,如果有任何输入有焦点,我们可以停止边界的消失。AFAIK,在jQuery中没有:focus selector,所以我不确定如何实现这一点。什么好主意吗?

15 个解决方案

#1


846  

jQuery 1.6+

jQuery added a :focus selector so we no longer need to add it ourselves. Just use $("..").is(":focus")

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

jQuery 1.5 and below

Edit: As times change, we find better methods for testing focus, the new favorite is this gist from Ben Alman:

编辑:随着时代的变化,我们找到了更好的方法来测试焦点,新的最爱是本·阿尔曼的这句话:

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

Quoted from Mathias Bynens here:

引用Mathias Bynens的话:

Note that the (elem.type || elem.href) test was added to filter out false positives like body. This way, we make sure to filter out all elements except form controls and hyperlinks.

注意(elem。添加|| element .href)测试以过滤身体等假阳性。通过这种方式,我们确保过滤掉除了表单控件和超链接之外的所有元素。

You're defining a new selector. See Plugins/Authoring. Then you can do:

定义一个新的选择器。看到插件/创作。然后你可以做:

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

or:

或者:

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

Any jQuery

If you just want to figure out which element has focus, you can use

如果您只想知道哪个元素有焦点,可以使用

$(document.activeElement)

If you aren't sure if the version will be 1.6 or lower, you can add the :focus selector if it is missing:

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

(function ( $ ) {
    var filters = $.expr[":"];
    if ( !filters.focus ) { 
        filters.focus = function( elem ) {
           return elem === document.activeElement && ( elem.type || elem.href );
        };
    }
})( jQuery );

#2


43  

CSS:

CSS:

.focus {
    border-color:red;
}

JQuery:

JQuery:

  $(document).ready(function() {

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

#3


19  

Here’s a more robust answer than the currently accepted one:

这里有一个比目前所接受的更有力的答案:

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

Note that the (elem.type || elem.href) test was added to filter out false positives like body. This way, we make sure to filter out all elements except form controls and hyperlinks.

注意(elem。添加|| element .href)测试以过滤身体等假阳性。通过这种方式,我们确保过滤掉除了表单控件和超链接之外的所有元素。

(Taken from this gist by Ben Alman.)

(摘自本·阿尔曼(Ben Alman)的这句话。)

#4


13  

April 2015 Update

Since this question has been around a while, and some new conventions have come into play, I feel that I should mention the .live method has been depreciated.

由于这个问题已经存在了一段时间,而且一些新的惯例已经开始发挥作用,我觉得我应该提一下。live方法已经贬值了。

In its place, the .on method has now been introduced.

在它的位置上,现在已经引入了。on方法。

Their documentation is quite useful in explaining how it works;

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

The .on() method attaches event handlers to the currently selected set of elements in the jQuery object. As of jQuery 1.7, the .on() method provides all functionality required for attaching event handlers. For help in converting from older jQuery event methods, see .bind(), .delegate(), and .live().

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

So, in order for you to target the 'input focused' event, you can use this in a script. Something like:

因此,为了让你锁定“输入焦点”事件,你可以在脚本中使用它。喜欢的东西:

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

This is quite robust and even allows you to use the TAB key as well.

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

#5


2  

I'm not entirely sure what you're after but this sounds like it can be achieved by storing the state of the input elements (or the div?) as a variable:

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

#6


1  

An alternative to using classes to mark the state of an element is the internal data store functionality.

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

P.S.: You are able to store booleans and whatever you desire using the data() function. It's not just about strings :)

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

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

And then it's just a matter of accessing the state of elements.

然后就是访问元素的状态。

#7


1  

Have you thought about using mouseOver and mouseOut to simulate this. Also look into mouseEnter and mouseLeave

您是否考虑过使用mouseOver和mouseOut来模拟这个。还可以查看mouseEnter和mouseLeave

#8


0  

Keep track of both states (hovered, focused) as true/false flags, and whenever one changes, run a function that removes border if both are false, otherwise shows border.

将这两种状态(挂起、集中)作为true/false标志进行跟踪,当其中一个状态发生变化时,运行一个函数,如果两个状态都为false,则删除边界,否则显示边界。

So: onfocus sets focused = true, onblur sets focused = false. onmouseover sets hovered = true, onmouseout sets hovered = false. After each of these events run a function that adds/removes border.

因此:onfocus set focus = true, onblur sets focus = false。onmouseover设置盘旋= true, onmouseout设置盘旋= false。在每个事件之后运行一个添加/删除边界的函数。

#9


0  

As far as I know, you can't ask the browser if any input on the screen has focus, you have to set up some sort of focus tracking.

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

I usually have a variable called "noFocus" and set it to true. Then I add a focus event to all inputs that makes noFocus false. Then I add a blur event to all inputs that set noFocus back to true.

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

I have a MooTools class that handles this quite easily, I'm sure you could create a jquery plugin to do the same.

我有一个非常容易处理这个问题的MooTools类,我相信您可以创建一个jquery插件来实现这一点。

Once that's created, you could do check noFocus before doing any border swapping.

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

#10


0  

There is no :focus, but there is :selected http://docs.jquery.com/Selectors/selected

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

but if you want to change how things look based on what is selected you should probably be working with the blur events.

但是,如果您想根据所选的内容改变事物的外观,您可能需要处理模糊事件。

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

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

#11


0  

There is a plugin to check if an element is focused: http://plugins.jquery.com/project/focused

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

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

#12


0  

I had a .live("focus") event set to select() (highlight) the contents of a text input so that the user wouldn't have to select it before typing a new value.

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

$(formObj).select();

$(formObj).select();

Because of quirks between different browsers, the select would sometimes be superseded by the click that caused it, and it would deselect the contents right after in favor of placing the cursor within the text field (worked mostly ok in FF but failed in IE)

由于不同浏览器之间的差异,选择有时会被引起选择的点击所取代,并且它会立即取消选择内容,以便将光标放在文本字段中(在FF中工作得很好,但在IE中失败)

I thought I could solve this by putting a slight delay on the select...

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

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

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

This worked fine and the select would persist, but a funny problem arose.. If you tabbed from one field to the next, the focus would switch to the next field before the select took place. Since select steals focus, the focus would then go back and trigger a new "focus" event. This ended up in a cascade of input selects dancing all over the screen.

这一招很管用,选择也会持续下去,但一个有趣的问题出现了。如果从一个字段切换到另一个字段,那么焦点将在选择发生之前切换到下一个字段。由于select窃取焦点,焦点将返回并触发一个新的“焦点”事件。这最终导致了输入选择在屏幕上跳来跳去。

A workable solution would be to check that the field still has focus before executing the select(), but as mentioned, there's no simple way to check... I ended up just dispensing with the whole auto highlight, rather than turning what should be a single jQuery select() call into a huge function laden with subroutines...

一个可行的解决方案是检查该字段在执行select()之前仍然有焦点,但如前所述,没有简单的方法来检查……我最终放弃了整个自动高亮显示,而不是将一个jQuery select()调用转换成一个包含大量子例程的大型函数……

#13


0  

if anyone cares there is a much better way to capture focus now, $(foo).focus(...)

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

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

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

#14


0  

What I wound up doing is creating an arbitrary class called .elementhasfocus which is added and removed within the jQuery focus() function. When the hover() function runs on mouse out, it checks for .elementhasfocus:

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

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

So if it doesn't have that class (read: no elements within the div have focus) the border is removed. Otherwise, nothing happens.

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

#15


-1  

Simple

简单的

 <input type="text" /> 



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

    alert("I am in Focus");

     });
 </script>

#1


846  

jQuery 1.6+

jQuery added a :focus selector so we no longer need to add it ourselves. Just use $("..").is(":focus")

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

jQuery 1.5 and below

Edit: As times change, we find better methods for testing focus, the new favorite is this gist from Ben Alman:

编辑:随着时代的变化,我们找到了更好的方法来测试焦点,新的最爱是本·阿尔曼的这句话:

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

Quoted from Mathias Bynens here:

引用Mathias Bynens的话:

Note that the (elem.type || elem.href) test was added to filter out false positives like body. This way, we make sure to filter out all elements except form controls and hyperlinks.

注意(elem。添加|| element .href)测试以过滤身体等假阳性。通过这种方式,我们确保过滤掉除了表单控件和超链接之外的所有元素。

You're defining a new selector. See Plugins/Authoring. Then you can do:

定义一个新的选择器。看到插件/创作。然后你可以做:

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

or:

或者:

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

Any jQuery

If you just want to figure out which element has focus, you can use

如果您只想知道哪个元素有焦点,可以使用

$(document.activeElement)

If you aren't sure if the version will be 1.6 or lower, you can add the :focus selector if it is missing:

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

(function ( $ ) {
    var filters = $.expr[":"];
    if ( !filters.focus ) { 
        filters.focus = function( elem ) {
           return elem === document.activeElement && ( elem.type || elem.href );
        };
    }
})( jQuery );

#2


43  

CSS:

CSS:

.focus {
    border-color:red;
}

JQuery:

JQuery:

  $(document).ready(function() {

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

#3


19  

Here’s a more robust answer than the currently accepted one:

这里有一个比目前所接受的更有力的答案:

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

Note that the (elem.type || elem.href) test was added to filter out false positives like body. This way, we make sure to filter out all elements except form controls and hyperlinks.

注意(elem。添加|| element .href)测试以过滤身体等假阳性。通过这种方式,我们确保过滤掉除了表单控件和超链接之外的所有元素。

(Taken from this gist by Ben Alman.)

(摘自本·阿尔曼(Ben Alman)的这句话。)

#4


13  

April 2015 Update

Since this question has been around a while, and some new conventions have come into play, I feel that I should mention the .live method has been depreciated.

由于这个问题已经存在了一段时间,而且一些新的惯例已经开始发挥作用,我觉得我应该提一下。live方法已经贬值了。

In its place, the .on method has now been introduced.

在它的位置上,现在已经引入了。on方法。

Their documentation is quite useful in explaining how it works;

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

The .on() method attaches event handlers to the currently selected set of elements in the jQuery object. As of jQuery 1.7, the .on() method provides all functionality required for attaching event handlers. For help in converting from older jQuery event methods, see .bind(), .delegate(), and .live().

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

So, in order for you to target the 'input focused' event, you can use this in a script. Something like:

因此,为了让你锁定“输入焦点”事件,你可以在脚本中使用它。喜欢的东西:

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

This is quite robust and even allows you to use the TAB key as well.

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

#5


2  

I'm not entirely sure what you're after but this sounds like it can be achieved by storing the state of the input elements (or the div?) as a variable:

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

#6


1  

An alternative to using classes to mark the state of an element is the internal data store functionality.

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

P.S.: You are able to store booleans and whatever you desire using the data() function. It's not just about strings :)

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

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

And then it's just a matter of accessing the state of elements.

然后就是访问元素的状态。

#7


1  

Have you thought about using mouseOver and mouseOut to simulate this. Also look into mouseEnter and mouseLeave

您是否考虑过使用mouseOver和mouseOut来模拟这个。还可以查看mouseEnter和mouseLeave

#8


0  

Keep track of both states (hovered, focused) as true/false flags, and whenever one changes, run a function that removes border if both are false, otherwise shows border.

将这两种状态(挂起、集中)作为true/false标志进行跟踪,当其中一个状态发生变化时,运行一个函数,如果两个状态都为false,则删除边界,否则显示边界。

So: onfocus sets focused = true, onblur sets focused = false. onmouseover sets hovered = true, onmouseout sets hovered = false. After each of these events run a function that adds/removes border.

因此:onfocus set focus = true, onblur sets focus = false。onmouseover设置盘旋= true, onmouseout设置盘旋= false。在每个事件之后运行一个添加/删除边界的函数。

#9


0  

As far as I know, you can't ask the browser if any input on the screen has focus, you have to set up some sort of focus tracking.

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

I usually have a variable called "noFocus" and set it to true. Then I add a focus event to all inputs that makes noFocus false. Then I add a blur event to all inputs that set noFocus back to true.

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

I have a MooTools class that handles this quite easily, I'm sure you could create a jquery plugin to do the same.

我有一个非常容易处理这个问题的MooTools类,我相信您可以创建一个jquery插件来实现这一点。

Once that's created, you could do check noFocus before doing any border swapping.

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

#10


0  

There is no :focus, but there is :selected http://docs.jquery.com/Selectors/selected

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

but if you want to change how things look based on what is selected you should probably be working with the blur events.

但是,如果您想根据所选的内容改变事物的外观,您可能需要处理模糊事件。

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

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

#11


0  

There is a plugin to check if an element is focused: http://plugins.jquery.com/project/focused

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

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

#12


0  

I had a .live("focus") event set to select() (highlight) the contents of a text input so that the user wouldn't have to select it before typing a new value.

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

$(formObj).select();

$(formObj).select();

Because of quirks between different browsers, the select would sometimes be superseded by the click that caused it, and it would deselect the contents right after in favor of placing the cursor within the text field (worked mostly ok in FF but failed in IE)

由于不同浏览器之间的差异,选择有时会被引起选择的点击所取代,并且它会立即取消选择内容,以便将光标放在文本字段中(在FF中工作得很好,但在IE中失败)

I thought I could solve this by putting a slight delay on the select...

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

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

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

This worked fine and the select would persist, but a funny problem arose.. If you tabbed from one field to the next, the focus would switch to the next field before the select took place. Since select steals focus, the focus would then go back and trigger a new "focus" event. This ended up in a cascade of input selects dancing all over the screen.

这一招很管用,选择也会持续下去,但一个有趣的问题出现了。如果从一个字段切换到另一个字段,那么焦点将在选择发生之前切换到下一个字段。由于select窃取焦点,焦点将返回并触发一个新的“焦点”事件。这最终导致了输入选择在屏幕上跳来跳去。

A workable solution would be to check that the field still has focus before executing the select(), but as mentioned, there's no simple way to check... I ended up just dispensing with the whole auto highlight, rather than turning what should be a single jQuery select() call into a huge function laden with subroutines...

一个可行的解决方案是检查该字段在执行select()之前仍然有焦点,但如前所述,没有简单的方法来检查……我最终放弃了整个自动高亮显示,而不是将一个jQuery select()调用转换成一个包含大量子例程的大型函数……

#13


0  

if anyone cares there is a much better way to capture focus now, $(foo).focus(...)

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

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

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

#14


0  

What I wound up doing is creating an arbitrary class called .elementhasfocus which is added and removed within the jQuery focus() function. When the hover() function runs on mouse out, it checks for .elementhasfocus:

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

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

So if it doesn't have that class (read: no elements within the div have focus) the border is removed. Otherwise, nothing happens.

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

#15


-1  

Simple

简单的

 <input type="text" /> 



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

    alert("I am in Focus");

     });
 </script>