How do I find out which DOM element has the focus?

后端 未结 16 1240
悲&欢浪女
悲&欢浪女 2020-11-22 03:12

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

16条回答
  •  情歌与酒
    2020-11-22 03:40

    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 (or maybe ) 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.

提交回复
热议问题