Using jQuery to test if an input has focus

2018-12-31 08:00发布

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.

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?

15条回答
闭嘴吧你
2楼-- · 2018-12-31 08:18

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:

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.

查看更多
刘海飞了
3楼-- · 2018-12-31 08:21

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.

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.

查看更多
公子世无双
4楼-- · 2018-12-31 08:22

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

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

查看更多
流年柔荑漫光年
5楼-- · 2018-12-31 08:23

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.

(Taken from this gist by Ben Alman.)

查看更多
泛滥B
6楼-- · 2018-12-31 08:23

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

查看更多
零度萤火
7楼-- · 2018-12-31 08:24

jQuery 1.6+

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

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:

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.

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:

(function ( $ ) {
    var filters = $.expr[":"];
    if ( !filters.focus ) { 
        filters.focus = function( elem ) {
           return elem === document.activeElement && ( elem.type || elem.href );
        };
    }
})( jQuery );
查看更多
登录 后发表回答