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

后端 未结 16 1218
悲&欢浪女
悲&欢浪女 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:33

    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;
      }
    }
    
    0 讨论(0)
  • 2020-11-22 03:39

    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:

    • activeElement Browser Compatibility
    • jQuery alternative for document.activeElement
    0 讨论(0)
  • 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 <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.

    0 讨论(0)
  • 2020-11-22 03:41

    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

    0 讨论(0)
  • 2020-11-22 03:43

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

    $("input#id").is(":active");
    
    0 讨论(0)
  • 2020-11-22 03:45

    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.

    0 讨论(0)
提交回复
热议问题