Get the Focused Element with JavaScript

By  on  

Ensuring that a website or web app is both accessible and usable, as well as functional, is paramount to a positive user experience for all users.  Users don't appreciate when we've done a good job, but they definitely know when we've done poorly.  One important part of app usability and accessibility is focus management, a task often overlooked by developers.

A prime example of poor focus management:  opening a modal upon clicking a triggering link, not focusing on the any element in the modal.  Even worse:  focusing on one of the modal's elements but not returning focus to its trigger element once it has been closed.  Ideally you would store a reference to the trigger, focus into the modal, and focus back on the trigger element when the modal is closed.

What about the times when you aren't aware of which element is focused though?  The document tells us which element is focused via the document.activeElement property!

The JavaScript

Retrieving the currently selected element is as easy as using document.activeElement:

var focusedElement = document.activeElement;

/* per my example:
	var triggerElement = document.activeElement;
	myModal = new MyModal({
		onOpen: function() {
			this.container.focus();
		},
		onClose: function() {
			triggerElement.focus();
		}
	});
*/

This property isn't simply reserved for traditionally focusable elements, like form fields and links, but also any element with a positive tabIndex set.

What I love about document.activeElement is that you don't need any type of event listener or delegated listener to keep track of what element is focused -- you can simply reference that one property at any time.  Of course you should do loads of testing before relying on a feature like this -- it seems ripe for cross-browser issues or race conditions.  All in all, however, I've been pleased with my use of it and its reliability!

Recent Features

  • By
    How to Create a RetroPie on Raspberry Pi – Graphical Guide

    Today we get to play amazing games on our super powered game consoles, PCs, VR headsets, and even mobile devices.  While I enjoy playing new games these days, I do long for the retro gaming systems I had when I was a kid: the original Nintendo...

  • By
    Introducing MooTools Templated

    One major problem with creating UI components with the MooTools JavaScript framework is that there isn't a great way of allowing customization of template and ease of node creation. As of today, there are two ways of creating: new Element Madness The first way to create UI-driven...

Incredible Demos

  • By
    MooTools FontChecker Plugin

    There's a very interesting piece of code on Google Code called FontAvailable which does a jQuery-based JavaScript check on a string to check whether or not your system has a specific font based upon its output width. I've ported this functionality to MooTools. The MooTools...

  • By
    Create a Photo Stack Effect with Pure CSS Animations or MooTools

    My favorite technological piece of Google Plus is its image upload and display handling.  You can drag the images from your OS right into a browser's DIV element, the images upload right before your eyes, and the albums page displays a sexy photo deck animation...

Discussion

  1. Darius Kruythoff

    If memory serves me, this breaks in IE9 within iframes.
    try/catch can help here.

  2. Gwyn

    Thanks, this seems to be a good technique. I hadn’t thought of using focus outside of links and form fields. Would you recommend this for a tabbed interface (switching focus between tabpanels?

  3. olivvv

    to detail our twitter exchange, wrapping document.activeElement in a setTimeout is necessary when you want to catch it onblur().

  4. MDN claims that on a Mac elements that are not a text input tends to *not* get focus assigned to them (https://developer.mozilla.org/en-US/docs/Web/API/document.activeElement). I haven’t experimented enough to provide any useful tips but it’s definitely something to look out for.

    • I did see that, though I experienced no issues on non-input elements, so I didn’t mention it.

  5. Karl Swedberg

    Hey David,

    Thanks for this post! I’m guessing the MDN note about elements other than text inputs not getting focus is referring to OS X Safari in particular. Also, the “Full Keyboard Access” setting in System Preferences > Keyboard > Shortcuts seems to have an effect on it. I put together a little demo: http://jsbin.com/dofiv/1/edit?html,js,console,output

    * With the default “Full Keyboard Access” setting — “Text boxes and lists only” — the radio inputs and button don’t get focus when clicked and can’t be tabbed into.
    * When “Full Keyboard Access” is set to “All controls,” only the radio with a tabindex attribute can be tabbed into, and that one doesn’t get focus when clicked.
    * I can’t tab into the a element regardless of the keyboard access setting, but it gets focus either way when clicked.
    * Interestingly, I can tab into the div element with tabindex and it gets focus click regardless of the keyboard access setting.

    For what it’s worth, here is what Sizzle does to determine the “active” element: https://github.com/jquery/sizzle/blob/master/src/sizzle.js#L1299
    And this comment explains how it handles the IE8-9 iframe error: https://github.com/jquery/sizzle/blob/master/src/sizzle.js#L603-L606

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!