How to check if element has focused child using javascript?

29,375

Solution 1

You can use Node.contains native DOM method for this.

el.contains(document.activeElement);

will check if activeElement is a descendant of el. If you have multiple elements to check, you can use a some function to iterate.

Solution 2

It is possible with Element's matches() method and with a simple selector string as follows:

let hasFocused = elem.matches(':focus-within:not(:focus)');
let focusedOrHasFocused = elem.matches(':focus-within');

Solution 3

Use CSS :focus pseudo-class in querySelectorAll()

setTimeout(function(){
  if (document.querySelectorAll("div :focus").length === 0)
    console.log("not focused");
  else
    console.log("focused")
}, 2000);
<div>
  <input type="text">
</div>

Solution 4

If you have issue where document.activeElement is returning <body> element after blur event, you just need to wrap it with setTimeout() and it will return correct element.

handleBlur() {
    setTimeout(() => { 
        console.log(document.activeElement); // this actually return active/focused element
    });
}

if you are using it standalone without timeout

handleBlur() {
    console.log(document.activeElement); // this is returning <body> element
}

Solution 5

Depending on your situation, using events might be more performant.

You can use the focusin and focusout events in that case.

const el = document.getElemen
el.addEventListener("focusin", () => alert("focus!"));
el.addEventListener("focusout", () => alert("blur!"));
Share:
29,375
Marc Gerrit Langer
Author by

Marc Gerrit Langer

Updated on July 09, 2022

Comments

  • Marc Gerrit Langer
    Marc Gerrit Langer almost 2 years

    I'm trying to remove all jQuery from my code. Until now I used

    if($(selector).find(':focus').length === 0){
      //focus is outside of my element
    }else{
      //focus is inside my element
    }
    

    to destinguish wether the focus is inside of one of my elements. Can you show me a jQuery-free way of doing it?

  • Marc Gerrit Langer
    Marc Gerrit Langer over 5 years
    I know this. But this solves not my problem. I want to know, if the active element is somewhere inside my element.
  • omri_saadon
    omri_saadon over 5 years
    You can get the element via getElementById and check if this is the activeElement. Added to my answer. @MarcGerritLanger
  • carl-johan.blomqvist
    carl-johan.blomqvist over 4 years
    Can you explain why you put it inside a setTimeout? Thanks!
  • Mohammad
    Mohammad over 4 years
    @carl-johan.blomqvist It is just for better understanding! For testing code you need to focus/unfocus on input. So timeout return response after 2 seconds
  • Aaron Beall
    Aaron Beall about 4 years
    Maybe your example could use a different id than div, that was a bit confusing
  • Kostiantyn Ko
    Kostiantyn Ko almost 3 years
    This one is really precise and simple. The only drawback is probably lack of IE <9 support, which is quite acceptable nowadays.