By Tony Peterson


2009-01-30 20:21:31 8 Comments

I would like to find out, in JavaScript, which element currently has focus. I've been looking through the DOM and haven't found what I need, yet. Is there a way to do this, and how?

The reason I was looking for this:

I'm trying to make keys like the arrows and enter navigate through a table of input elements. Tab works now, but enter, and arrows do not by default it seems. I've got the key handling part set up but now I need to figure out how to move the focus over in the event handling functions.

16 comments

@JW. 2009-01-30 20:24:55

Use document.activeElement, it is supported in all major browsers.

Previously, if you were trying to find out what form field has focus, you could not. To emulate detection within older browsers, add a "focus" event handler to all fields and record the last-focused field in a variable. Add a "blur" handler to clear the variable upon a blur event for the last-focused field.

If you need to remove the activeElement you can use blur; document.activeElement.blur(). It will change the activeElement to body.

Related links:

@Stewart 2010-07-02 12:32:44

If no element has been focused, what does document.activeElement return? Can we rely on it to be consistent between those browsers that support it?

@JW. 2010-07-02 15:19:37

Not sure about IE, but FF and Safari both return the BODY element.

@Barry 2011-09-20 22:01:50

do we have access to know which element was previously focused?

@JW. 2011-09-21 17:30:20

No, you'd have to keep track of that yourself.

@Rudie 2012-10-22 22:40:32

activeElement actually doesn't return the focused element. Any element can have focus. If a document has 4 'scrolldivs', 0 or 1 of those divs is scrollable by arrow keys. If you click one, that div is focused. If you click outside all, the body is focused. How do you find out which scrolldiv is focused? jsfiddle.net/rudiedirkx/bC5ke/show (check console)

@mklement0 2012-12-22 05:20:00

@Rudie, @Stewart: I've built on your fiddle to create a more elaborate playground: jsfiddle.net/mklement/72rTF. You'll find that the only major browser (as of late 2012) that can actually focus such a div is Firefox 17, and only by tabbing to it. The types of elements that ALL major browsers return via document.activeElement are restricted to input-related elements. If no such element has the focus, all major browsers return the body element - except IE 9, which returns the html element.

@mklement0 2012-12-22 05:25:36

@JW: IE (as of v9) returns the html element. Current versions (as of late 2012) of Safari, Chrome, Firefox, Opera all return the body element.

@Rob W 2013-03-30 17:28:17

In XHTML documents, 'activeElement' in document is false in Chrome (26). document.querySelector(':focus') works fine though, if you want to know if any input element is focused.

@Marco Luglio 2013-04-12 16:49:23

Not sure if it helps, but you can make an element such as a div receive keyboard focus by including the attribute tabindex="0"

@robocat 2013-07-02 02:11:41

Any access to document.activeElement should be wrapped in a try catch as under some circumstances it can throw an exception (not just IE9 AFAIK). See bugs.jquery.com/ticket/13393 and bugs.jqueryui.com/ticket/8443

@inanutshellus 2014-06-11 16:11:24

I updated @mklement / Rudie's jsfiddle. As facildelembrar stated, you can access it with tabindex. See jsfiddle.net/72rTF/34

@Ken 2020-05-01 23:27:56

I am not sure why people say it is not supported .. as it seems to have been supported eons ago .. w3schools.com/jsref/prop_document_activeelement.asp

@1j01 2016-11-29 18:51:04

By itself, document.activeElement can still return an element if the document isn't focused (and thus nothing in the document is focused!)

You may want that behavior, or it may not matter (e.g. within a keydown event), but if you need to know something is actually focused, you can additionally check document.hasFocus().

The following will give you the focused element if there is one, or else null.

var focused_element = null;
if (
    document.hasFocus() &&
    document.activeElement !== document.body &&
    document.activeElement !== document.documentElement
) {
    focused_element = document.activeElement;
}

To check whether a specific element has focus, it's simpler:

var input_focused = document.activeElement === input && document.hasFocus();

To check whether anything is focused, it's more complex again:

var anything_is_focused = (
    document.hasFocus() &&
    document.activeElement !== null &&
    document.activeElement !== document.body &&
    document.activeElement !== document.documentElement
);

Robustness Note: In the code where it the checks against document.body and document.documentElement, this is because some browsers return one of these or null when nothing is focused.

It doesn't account for if the <body> (or maybe <html>) had a tabIndex attribute and thus could actually be focused. If you're writing a library or something and want it to be robust, you should probably handle that somehow.


Here's a (heavy airquotes) "one-liner" version of getting the focused element, which is conceptually more complicated because you have to know about short-circuiting, and y'know, it obviously doesn't fit on one line, assuming you want it to be readable.
I'm not gonna recommend this one. But if you're a 1337 hax0r, idk... it's there.
You could also remove the || null part if you don't mind getting false in some cases. (You could still get null if document.activeElement is null):

var focused_element = (
    document.hasFocus() &&
    document.activeElement !== document.body &&
    document.activeElement !== document.documentElement &&
    document.activeElement
) || null;

For checking if a specific element is focused, alternatively you could use events, but this way requires setup (and potentially teardown), and importantly, assumes an initial state:

var input_focused = false;
input.addEventListener("focus", function() {
    input_focused = true;
});
input.addEventListener("blur", function() {
    input_focused = false;
});

You could fix the initial state assumption by using the non-evented way, but then you might as well just use that instead.

@vegemite4me 2017-10-20 11:20:01

I have found the following snippet to be useful when trying to determine which element currently has focus. Copy the following into the console of your browser, and every second it will print out the details of the current element that has focus.

setInterval(function() { console.log(document.querySelector(":focus")); }, 1000);

Feel free to modify the console.log to log out something different to help you pinpoint the exact element if printing out the whole element does not help you pinpoint the element.

@rplaurindo 2016-07-17 05:52:57

If you want to get a object that is instance of Element, you must use document.activeElement, but if you want to get a object that is instance of Text, you must to use document.getSelection().focusNode.

I hope helps.

@1j01 2016-11-29 19:10:50

Better in what way?

@rplaurindo 2016-11-29 19:22:34

Open your browser’s inspector, click on any place of the page, past this document.getSelection().focusNode.parentElement and tap Enter. After that, past document.activeElement and do it samething. ;)

@1j01 2016-12-01 02:37:37

With this comment box focused, document.activeElement gives the <textarea> whereas document.getSelection().focusNode gives the <td> that contains the <textarea> (and document.getSelection().focusNode.parentElement gives the <tr> containing the <td>)

@rplaurindo 2016-12-01 03:53:32

Sorry, my apologies. I didn’t explain it well. If you want to get a object that is instance of Element, you must to use document.activeElement, but if you want to get a object that is instance of Text, you must to use document.getSelection().focusNode. Please, test it again. I hope I helped.

@1j01 2016-12-02 06:45:04

The question is asking for which element currently has focus. And the focusNode isn't guaranteed to be a text node either.

@rplaurindo 2016-12-02 12:29:09

Yes, but the activeElement never will return a Text object. document.getSelection().focusNode guarantees a instance of Node, that cans to be a Text or a Element after click in an element, for example. It's not a question of being better, but more appropriate.

@1j01 2016-12-03 04:08:34

But the question asked for an element, i.e. an Element. It's fine (in my opinion) to answer a question by mentioning a similar situation under which you'd want a different solution, but "if you want to get a text node" isn't very descriptive. What did you use this for, for instance?

@rplaurindo 2016-12-03 21:31:08

Yes, the question was about a element. I took advantage of it and added the information to a different case. It is important note that some people make confusion, and believe that a text node is an element, when in fact, element is what encapsulates a text. Being Element and Text instances of Node, but a Text doesn’t is an Element. So... I used for get an object that was selected on HTML, then show a tooltip above it.

@1j01 2016-12-03 21:39:23

Okay, yeah, that's definitely a different case. Selection isn't focus.

@rplaurindo 2016-12-03 21:53:01

It really is not. But could be a click event case over a text rather than a selection. So much so that the FOCUSNode attribute exists for the object returned by the getSelection method.

@Chase Choi 2018-07-23 09:35:30

it's very useful when you need to set different action for input things. though it's not about getting current element when focusout triggers, guess no better way. there's no use case to get the element when focusout. if you need, that is better use mouseout.

@William Denniss 2011-08-27 17:33:54

If you can use jQuery, it now supports :focus, just make sure you are using version 1.6+.

This statement will get you the currently focused element.

$(":focus")

From: How to select an element that has focus on it with jQuery

@Harry Pehkonen 2017-10-13 03:16:36

This is good, but how does jQuery do it? document.activeElement? I found this: return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);

@Nathan K 2015-03-01 07:36:58

There are potential problems with using document.activeElement. Consider:

<div contentEditable="true">
  <div>Some text</div>
  <div>Some text</div>
  <div>Some text</div>
</div>

If the user focuses on an inner-div, then document.activeElement still references the outer div. You cannot use document.activeElement to determine which of the inner div's has focus.

The following function gets around this, and returns the focused node:

function active_node(){
  return window.getSelection().anchorNode;
}

If you would rather get the focused element, use:

function active_element(){
  var anchor = window.getSelection().anchorNode;
  if(anchor.nodeType == 3){
        return anchor.parentNode;
  }else if(anchor.nodeType == 1){
        return anchor;
  }
}

@Tim Down 2015-07-19 09:59:11

That's not really a problem with document.activeElement: the inner <div> elements actually can't receive focus, as you can see visually by setting the :focus pseudo-class to something visible (example: jsfiddle.net/4gasa1t2/1). What you're talking about is which of the inner <div>s contains the selection or caret, which is a separate issue.

@Nate Whittaker 2014-08-06 19:32:17

document.activeElement may default to the <body> element if no focusable elements are in focus. Additionally, if an element is focused and the browser window is blurred, activeElement will continue to hold the focused element.

If either of these two behaviors are not desirable, consider a CSS-based approach: document.querySelector( ':focus' ).

@Manfred 2015-05-10 13:49:30

Cool, yes in my case your approach made absolutly sense. I can set my focusable elements with 'tabindex="-1" ', if none of them has focus (let's say, some text or picture, that I don't care about) the document.querySelector( ':focus') returns null.

@1j01 2016-11-29 19:12:54

See my answer to avoid using querySelector: stackoverflow.com/a/40873560/2624876

@Joel S 2010-02-04 12:36:56

A little helper that I've used for these purposes in Mootools:

FocusTracker = {
    startFocusTracking: function() {
       this.store('hasFocus', false);
       this.addEvent('focus', function() { this.store('hasFocus', true); });
       this.addEvent('blur', function() { this.store('hasFocus', false); });
    },

    hasFocus: function() {
       return this.retrieve('hasFocus');
    }
}

Element.implement(FocusTracker);

This way you can check if element has focus with el.hasFocus() provided that startFocusTracking() has been called on the given element.

@Arne 2012-02-14 19:29:01

If you're using jQuery, you can use this to find out if an element is active:

$("input#id").is(":active");

@Daniel Hartmann 2012-01-13 11:55:48

With dojo, you can use dijit.getFocus()

@Andy E 2011-10-19 13:01:06

document.activeElement is now part of the HTML5 working draft specification, but it might not yet be supported in some non-major/mobile/older browsers. You can fall back to querySelector (if that is supported). It's also worth mentioning that document.activeElement will return document.body if no element is focused — even if the browser window doesn't have focus.

The following code will work around this issue and fall back to querySelector giving a little better support.

var focused = document.activeElement;
if (!focused || focused == document.body)
    focused = null;
else if (document.querySelector)
    focused = document.querySelector(":focus");

An addition thing to note is the performance difference between these two methods. Querying the document with selectors will always be much slower than accessing the activeElement property. See this jsperf.com test.

@Wookai 2009-01-30 20:34:18

As said by JW, you can't find the current focused element, at least in a browser-independent way. But if your app is IE only (some are...), you can find it the following way :

document.activeElement

EDIT: It looks like IE did not have everything wrong after all, this is part of HTML5 draft and seems to be supported by the latest version of Chrome, Safari and Firefox at least.

@Crescent Fresh 2009-01-31 00:37:42

FF3 too. This is actually part of the HTML5 spec around "focus management".

@gregers 2009-06-09 15:02:39

It works in the current version of Chrome and Opera (9.62). Does not work in Safari 3.2.3 on OS X, but it works in Safari 4 that was released yesterday :)

@Sebas 2012-06-20 23:12:35

still the same for chrome 19 :S

@Dawn 2012-07-05 11:03:51

It only works in chrome (20) / safari (5.1.3) when you use the keyboard to tab onto the element. If you click on it then neither the jquery :focus selector nor the document.activeElement succeeds in returning what you clicked on (returning undefined and document body element respectively). PS I can't believe this thread is 2 years old and there are still regression problems on webkit, along with the one where skip links don't work, but so much work is being done with adding experimental css3. Think I may go back to recommending firefox to my family and friends.

@marksyzm 2013-09-10 13:39:30

^^ document.activeElement is fine when you click to focus on a text area or other input. If it is a link it won't focus when clicked on (in page or obviously otherwise).

@Cornelius 2020-03-21 12:46:21

It returns 'body' for most of the elements. Pretty much useless.

@rjmunro 2011-08-04 23:20:21

Reading other answers, and trying myself, it seems document.activeElement will give you the element you need in most browsers.

If you have a browser that doesn't support document.activeElement if you have jQuery around, you should be able populate it on all focus events with something very simple like this (untested as I don't have a browser meeting those criteria to hand):

if (typeof document.activeElement === 'undefined') { // Check browser doesn't do it anyway
  $('*').live('focus', function () { // Attach to all focus events using .live()
    document.activeElement = this; // Set activeElement to the element that has been focussed
  });
}

@DeezCashews 2011-03-10 23:10:36

JQuery does support the :focus pseudo-class as of current. If you are looking for it in the JQuery documentation, check under "Selectors" where it points you to the W3C CSS docs. I've tested with Chrome, FF, and IE 7+. Note that for it to work in IE, <!DOCTYPE... must exist on the html page. Here is an example assuming you've assigned an id to the element that has focus:

$(":focus").each(function() {
  alert($(this).attr("id") + " has focus!");
});

@Martijn 2015-12-15 13:51:57

You should (always?) use this.id instead of $(this).attr('id'), or at least (when you allready have your jQuery object) $(this)[0].id. Native Javascript at this level is WAY faster and more efficient. Might not be noticable in this case, but systemwide you will notice a difference.

@Jason 2010-09-08 18:47:29

I liked the approach used by Joel S, but I also love the simplicity of document.activeElement. I used jQuery and combined the two. Older browsers that don't support document.activeElement will use jQuery.data() to store the value of 'hasFocus'. Newer browsers will use document.activeElement. I assume that document.activeElement will have better performance.

(function($) {
var settings;
$.fn.focusTracker = function(options) {
    settings = $.extend({}, $.focusTracker.defaults, options);

    if (!document.activeElement) {
        this.each(function() {
            var $this = $(this).data('hasFocus', false);

            $this.focus(function(event) {
                $this.data('hasFocus', true);
            });
            $this.blur(function(event) {
                $this.data('hasFocus', false);
            });
        });
    }
    return this;
};

$.fn.hasFocus = function() {
    if (this.length === 0) { return false; }
    if (document.activeElement) {
        return this.get(0) === document.activeElement;
    }
    return this.data('hasFocus');
};

$.focusTracker = {
    defaults: {
        context: 'body'
    },
    focusedElement: function(context) {
        var focused;
        if (!context) { context = settings.context; }
        if (document.activeElement) {
            if ($(document.activeElement).closest(context).length > 0) {
                focused = document.activeElement;
            }
        } else {
            $(':visible:enabled', context).each(function() {
                if ($(this).data('hasFocus')) {
                    focused = this;
                    return false;
                }
            });
        }
        return $(focused);
    }
};
})(jQuery);

@Pylinux 2015-07-30 10:30:59

Could this be replaced by @William Denniss's $("*:focus") ?

@Jason 2015-08-21 19:33:34

I suppose it could. I wrote this a long time ago and never had a reason to revisit a better solution now that it is 5 years later. Try it out! I might just do the same. I less plugin on our site! :)

@Tony Peterson 2009-05-18 12:48:51

Just putting this here to give the solution I eventually came up with.

I created a property called document.activeInputArea, and used jQuery's HotKeys addon to trap keyboard events for arrow keys, tab and enter, and I created an event handler for clicking into input elements.

Then I adjusted the activeInputArea every time focus changed, so I could use that property to find out where I was.

It's easy to screw this up though, because if you have a bug in the system and focus isn't where you think it is, then its very hard to restore the correct focus.

Related Questions

Sponsored Content

58 Answered Questions

[SOLVED] How do I check if an element is hidden in jQuery?

41 Answered Questions

[SOLVED] How do I loop through or enumerate a JavaScript object?

32 Answered Questions

[SOLVED] Remove all child elements of a DOM node in JavaScript

  • 2010-10-17 20:51:00
  • Polaris878
  • 921300 View
  • 918 Score
  • 32 Answer
  • Tags:   javascript dom

81 Answered Questions

[SOLVED] How do I detect a click outside an element?

14 Answered Questions

[SOLVED] How can I select an element by name with jQuery?

15 Answered Questions

[SOLVED] How to move an element into another element?

  • 2009-08-14 20:14:45
  • Mark Richman
  • 1146014 View
  • 1725 Score
  • 15 Answer
  • Tags:   javascript jquery html

37 Answered Questions

26 Answered Questions

[SOLVED] How can I tell if a DOM element is visible in the current viewport?

17 Answered Questions

[SOLVED] How to decide when to use Node.js?

15 Answered Questions

Sponsored Content