Skip to content

Instantly share code, notes, and snippets.

@cowboy
Created June 23, 2010 14:47
Show Gist options
  • Save cowboy/450017 to your computer and use it in GitHub Desktop.
Save cowboy/450017 to your computer and use it in GitHub Desktop.
:focus - get the currently focused element
// Public domain, really.
jQuery.expr[':'].focus = function( elem ) {
return elem === document.activeElement && ( elem.type || elem.href );
};
@cowboy
Copy link
Author

cowboy commented Jun 23, 2010

Thanks, Diego.

@jaubourg
Copy link

Isn't that a lot of troubles/operations just to get the currently focussed element?

I mean, you will select all those elements first, then apply the focus filter on the list? Why not have a jQuery.focussed function that would return jQuery( document.activeElement ) or false if activeElement doesn't have a type or href property?

Seems to me you're pushing for innefficient code by putting this feature where you put it... if you get my grip.

@dperini
Copy link

dperini commented Jun 23, 2010

Somebody argued that "type" is also an attribute of "script" and "style" elements.
I agree... but these elements are invisible so they would never become the document.activeElement :)

@cowboy
Copy link
Author

cowboy commented Jun 23, 2010

Julian, I couldn't agree more. The most common use case is "which element has focus" and not of "which of these elements has focus" like the selector implies. Of course, if QSA supports it, it's probably a legitimate selector. Either way, this code should have a warning on it, like "If you just want to get the currently focused element, don't do $(':focus'), do $.getFocusedElement()!!!"

@jaubourg
Copy link

Well, you could add an optimisation for $(':focus') in jQuery() :P

EDIT: I was talking more about the fact your approach makes people select nodes then control if one of them is focussed whereas the performant approach would be to get the currently focussed element and control if it corresponds to what you're looking for. Getting the focussed element out of a set of elements is not that an alien request, it's the performance of the selector approach I have a problem with.

@cowboy
Copy link
Author

cowboy commented Jun 23, 2010

Julian, yeah.. this is kinda gross..

// I'm lazy.
jQuery.getFocusedElement = function() {
  return $(document.activeElement).filter(':focus');
};

// A little less lazy.
jQuery.getFocusedElement = function() {
  var elem = document.activeElement;
  return $( elem && ( elem.type || elem.href ) ? elem : [] );
};

An optimization in jQuery / Sizzle for ':focus' would be much nicer!

@dperini
Copy link

dperini commented Jun 23, 2010

I thought it was better adding this information here instead of let it get lost between tweets...
Keep in mind that IE & newer FF/Safari have a "document.hasFocus()" method to resolve that specific "question".
"hasFocus()" should be more precise of our simple test and NWMatcher forks on that method for consistency with browsers themselves.
I agree too it would be better having a jQuery selector for that. It will be faster and to be honest :focus has been in the draft CSS2 specifications since 12 years, so contrary to full CSS compliance statements this is something that have been missing and weirdly unsupported by jQuery which is no more than 5 years old.
Here the relevant specification draft:
http://www.w3.org/TR/1998/REC-CSS2-19980512/

@mathiasbynens
Copy link

@dperini:

Somebody argued that "type" is also an attribute of "script" and "style" elements.
I agree... but these elements are invisible so they would never become the document.activeElement :)

Unless someone would apply display: block to those elements [example].

@dperini
Copy link

dperini commented Jun 23, 2010

@mathiasbynens,
ha...ha... what for ?
If you want to fake the test or the selector engine or the browsers CSS engine you will be able to do it under all circumstances. Just set the "type" or "href" property of each element in the page. The check could test the nodeName of valid focusable elements to make it stronger but it will be useful only for you and your non-standard approach and that has no value for me.

@mathiasbynens
Copy link

@dperini I wasn’t trying to be funny, just pointing it out. I very much agree it would be nonsensical to write additional code to take into account these weird and highly unlikely situations.

@gnarf
Copy link

gnarf commented May 4, 2011

Should this maybe also check for some element that is not an input that has tabIndex ?

@pnina
Copy link

pnina commented Jun 2, 2011

please you send me a sample how to use this selector (:focus) ?

@cowboy
Copy link
Author

cowboy commented Jun 2, 2011

It works like this: :focus selector (note that recent versions of jQuery include this selector)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment