46

Is there something I can do like this (perhap via a plugin)

if ( ! $('form#contact input]').hasFocus()) {
 $('form#contact input:first]').focus();
}

Basically, set focus to the first input, but only if the user has not already clicked into anything?

I know this will work too, but is there anything more elegant?

$(function() {
 var focused = false;
 $('form#contact input]').focus(function() {
 focused = true;
 }); 
 setTimeout(function() {
 if ( ! focused) { 
 $('form#contact input:first]').focus();
 }
 }, 500);
});
asked Apr 21, 2010 at 14:23
0

10 Answers 10

63

There is no native solution but yes there is a more elegant way you can do it:

jQuery.extend(jQuery.expr[':'], {
 focus: "a == document.activeElement"
});

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

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

or:

$("input:focus").doStuff();
answered Apr 21, 2010 at 14:32

5 Comments

Perhaps you should submit this for newer versions of jQuery, it would be useful.
Any idea why jQuery.expr uses == rather than ===?
This can cause false positives. See stackoverflow.com/questions/967096/… for more information and a simple fix (thanks to Ben Alman and Diego Perini).
@MLL: Is it just eval()'d? I've always written my custom selectors in a different way.
as mentioned by others jquery now natively supports this :focus api.jquery.com/focus-selector
27

$('input:focus')

It's CSS. You don't need to create a "custom selector." It already exists! http://www.w3schools.com/CSS/pr_pseudo_focus.asp

Just attach whatever process you want to do to that selector, and it will weed it out if the element in question is not focused. I did this recently to keep a keyup from instantiating an email input error check when the e-mail input wasn't being used.

If all you're trying to do is check if the user has focused on anything themselves, just do this:

if($('input:focus').size() == 0){
 /* Perform your function! */
}
answered Apr 21, 2010 at 14:38

5 Comments

You are wrong. jQuery, unlike CSS, does not have :focus or :hover selectors.
jQuery uses CSS selectors. If it works in CSS, it works in jQ. Trust me. If you have any doubt, try the form in this page and then inspect the JS: ddrewdesign.com/contact Trigger code is on line 124. I haven't tried :hover before though, so I can't speak for that. The trick is getting the JS to do the legwork so it is able to check, so you have to put it inside of an action of some sort.
Correct. jQ only recognizes pseudoclasses that its browser recognizes.
Someone ran through and downvoted (almost) all these answers for no readily apparent reason so +1 from me to counter
I'd say it would work due to being passed directly to querySelectorAll() or one of its cousins. If you used it with a jQuery custom thing, such as :input, it might not work (haven't tested it, would depend on how jQuery tokenizes the selector).
12

jQuery 1.6 now has a dedicated :focus selector.

answered May 10, 2011 at 12:59

Comments

9

I had trouble with cletus approach, using jQuery 1.3.2 and Firefox 3.6.8, because the string "a == document.activeElement" was not a valid function.

I fixed it defining a function for the focus key. In fact, all other keys defined in jQuery.expr[':'] are defined as functions. Here's the code:

jQuery.extend(jQuery.expr[':'], {
 focus: function(e){ return e == document.activeElement; }
});

So, now it works as expected.

However, I was experiencing some strange behaviour in Firefox 3.6.8 (maybe a bug in FF?). If I clicked on an input text while the page was rendering, and if I called is(":focus") on page load, I would get an error from the browser, reported by FireBug, and the script would break.

To solve this, I surrounded the code with a try...catch block, returning false on error. Use it if you want to prevent your users from experiencing the same error:

jQuery.extend(jQuery.expr[':'], {
 focus: function(e){
 try{ return e == document.activeElement; }
 catch(err){ return false; }
 }
});
answered Aug 13, 2010 at 15:32

Comments

8

Frustratingly difficult to find a solution to this problem considering the solution is actually very simple:

if (document.activeElement == this) {
 // has focus
}
if (document.activeElement != this) {
 // does not have focus
}

answered Aug 3, 2015 at 11:07

Comments

7

No, there isn't.

However, you can simulate it like this:

$(':input')
 .data('focused', false)
 .focus(function() { $.data(this, 'focused', true); })
 .blur(function() { $.data(this, 'focused', false); });
answered Apr 21, 2010 at 14:26

3 Comments

all the answer's were except Vincent's (click on them). I'm +1'ing them all to counter that.
Don't know about the downvotes. Perhaps they did it when your answer was only the first line. Anyway, I gave you a +1 :)
Note that you could use $(this).data('focused', true) now, etc.
3
answered Apr 21, 2010 at 14:28

1 Comment

Someone ran through and downvoted (almost) all these answers for no readily apparent reason so +1 from me to counter
2

Here is a succinct way to do it.

$(document.activeElement)

or to plug it into your example..

if ($('form#contact input]')[0]!=$(document.activeElement)) { ... }
answered Apr 15, 2011 at 13:18

2 Comments

The bottom one will never work as they will always be different jQuery collections.
A minor change would work. A jquery element is an array with the javascript element in first position. It would work if you tweaked it to ($('form#contact input]')[0]!=document.activeElement) { ... } Your answer really helped me.
1

I know this is an old question, but may be my solution will help someone :)

since this didnt worked for me:

if ($(this)!=$(document.activeElement)) { ... }

..were "this" is returned from blur function. So i did this:

if ($(document.activeElement).attr("class") != "input_textbox"){ ... }
answered Feb 18, 2013 at 12:40

1 Comment

The first solution wraps both in jQuery collections for no reason, and it will also fail as they will be the different objects. The second one is rarely a good way to check if an element is the one you match something as elements can have multiple classes.
-2
 $('*:focus')

(Necro ftw, but still valid and useful)

answered Jan 28, 2014 at 12:06

2 Comments

The * shouldn't be required.
Necroing is fine - questions and answers are timeless, and there's even a couple of badges for answering a question much later with a good score, like Necromancer. However, I am downvoting this as it provides no guidance on how to check if specific elements have focus. Are you able to add that?

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.