embracethefuture
embracethefuture

Reputation: 705

How to focus an element only if it isn't currently focused?

The reason I want to do this is because there's some unwanted styling behavior going on when I click on an already focused input. I'd rather it only apply when I first focus it.

I have a basic useRef that holds my inputEl, and I want it so that clicking on the icon (which is a sibling) next to the input element will focus the relevant field, but only if it isn't already focused (if it's already focused, it should do nothing).

So I tried to put the following onClick on the Icon element.

onClick={() => {
  if (document.activeElement !== inputEl.current) {
    inputEl.current.focus();
  }
}}

This condition doesn't work because every time a click happens, the activeElement clears and defaults to the body and so the check fails and I focus again. Not 100% sure why that happens. For some context, the project is bootstrapped by CRA and the icon with this onClick is a Font Awesome React icon. There's nothing notable about the input element except that it has a ref property of inputEl. As I'm using useRef, you probably guessed, but this is inside of a functional component.

I can probably think of some pretty convoluted ways to solve this issue but I'll defer until I get an answer to see if there's a cleaner way. I was thinking maybe setting some state value after focusing, using that in the check and using a useEffect to return the state value to null when the element unfocuses or something like that. Is that an okay idea? Is there a simpler method I'm missing?

Edit: I think I phrased the issue poorly. What I'm trying to solve is the problem that every time I click the icon, it briefly unfocuses the field before refocusing it, which causes my focus transitions to happen on every click.

Upvotes: 4

Views: 1357

Answers (1)

Saeed Shamloo
Saeed Shamloo

Reputation: 6574

change focus happens when mousedown event fires on element, you can use mousedown event handler to prevent change the active element.

onMouseDown={(e) => {
  if (document.activeElement == inputEl.current) {
   e.preventDefault();
  }else{ /*Do focus on input*/ }
}}

Upvotes: 3

Related Questions