231

I know this shouldn't be that hard, but I couldn't find the answer on Google.

I want to execute a piece of javascript that will clear the focus from whatever element it is on without knowing ahead of time which element the focus is on. It has to work on firefox 2 as well as more modern browsers.

Is there a good way to do this?

Jon Seigel
  • 12,251
  • 8
  • 58
  • 92
Andres
  • 5,012
  • 3
  • 24
  • 36

9 Answers9

252

Answer: document.activeElement

To do what you want, use document.activeElement.blur()

If you need to support Firefox 2, you can also use this:

function onElementFocused(e)
{
    if (e && e.target)
        document.activeElement = e.target == document ? null : e.target;
} 

if (document.addEventListener) 
    document.addEventListener("focus", onElementFocused, true);
Donald Duck
  • 8,409
  • 22
  • 75
  • 99
jps
  • 11,347
  • 3
  • 23
  • 19
  • 8
    If Firefox 2, with 0.66% browser share, is a deal breaker ... I have a fix, which is in my edited answer. – jps Mar 26 '10 at 02:06
  • 27
    In 2013, the browser share of Firefox 2 is substantially less than 0.66%, and the simple `document.activeElement.blur()` is the best way to achieve this effect. – chowey Nov 28 '13 at 21:57
  • 4
    I get the following: `Property 'blur' does not exist on type 'Element'.ts(2339)` – YTG Feb 08 '21 at 12:37
  • @YTG See the answer I posted to this question, which addresses this problem. – Wilco Apr 13 '21 at 10:16
  • document.activeElement is a read-only property. You cannot assign to it anything – Jakub Kurdziel Jun 28 '21 at 14:39
96

.focus() and then .blur() something else arbitrary on your page. Since only one element can have the focus, it is transferred to that element and then removed.

Kevin Reid
  • 37,492
  • 13
  • 80
  • 108
  • Is there a way to make an invisible element that has focus? – Andres Mar 26 '10 at 01:45
  • 1
    I'm not an expert on the best way to do that; but you could certainly position it off-screen or outside of the bounds of an `overflow: clip` styled element. But you could just use a field that already exists on the page. Or create one just for the purpose and remove it again. – Kevin Reid Mar 26 '10 at 02:02
  • I think that setting the focus to an element off-screen will force a scroll to that element. However, you can create an invisible element for the purpose. That being said, some browsers may have a hard time to remove the caret. Just blur() would probably work better. You could still get keys with a keyup (keydown) event handler. – Alexis Wilke Jun 04 '15 at 23:54
  • 5
    This answer is out of date and doesn't apply in the year 2017. Use activeElement instead, as in https://stackoverflow.com/a/2520670/39808 – Paul Fisher Mar 17 '17 at 18:30
  • It still works, just longer and moves the focus (which may interfere with TAB navigation) Also it's not immediately apparent what should "something else arbitrary" be. – user202729 Aug 21 '18 at 09:19
  • Don't do this. Some screen readers will follow the keyboard focus, and will read out the change in focus. – Corey Mar 18 '20 at 19:05
64
document.activeElement.blur();

Works wrong on IE9 - it blurs the whole browser window if active element is document body. Better to check for this case:

if (document.activeElement != document.body) document.activeElement.blur();
pwnzor1337
  • 641
  • 5
  • 2
  • 4
    I get `Property 'blur' does not exist on type 'Element'.ts(2339)` – YTG Feb 08 '21 at 12:38
  • 3
    you would need to cast as HTMLElement. – unknown_boundaries Jun 21 '21 at 03:26
  • Although IE9 has fallen by the wayside, what it was doing actually was somewhat sensible, and supporting this behavior seems like a good idea, should other browsers decide to implement this same behavior. Heck, chrome could implement a flag for this behavior tomorrow. – Devin Rhode Mar 27 '23 at 12:29
61

None of the answers provided here are completely correct when using TypeScript, as you may not know the kind of element that is selected.

This would therefore be preferred:

if (document.activeElement instanceof HTMLElement)
    document.activeElement.blur();

I would furthermore discourage using the solution provided in the accepted answer, as the resulting blurring is not part of the official spec, and could break at any moment.

Wilco
  • 719
  • 5
  • 8
  • A similar solution with the newer `as` type cast: `(document.activeElement as HTMLElement).blur()`. – Tim Dec 27 '21 at 16:59
  • 1
    I prefer `document.activeElement?.blur && document.activeElement.blur()` – foobored May 18 '22 at 10:09
  • 1
    `as` does not ensure that the element is an HTMLElement. It just satisfies the type checker. It will crash if `blur` is not defined. – Raine Revere Dec 07 '22 at 17:05
9

For anyone using typescript, use

(document.activeElement as HTMLElement).blur();

This makes sure the element is of type HTMLElement

m_j_alkarkhi
  • 337
  • 4
  • 14
  • 1
    This does not ensure that the element is an HTMLElement. It just satisfies the type checker. Wrap it in `if(document.activeElement instanceof HTMLElement)` to avoid crashing on non-HTML DOM nodes. – Raine Revere Dec 07 '22 at 17:05
3

I prefer document.activeElement?.blur && document.activeElement.blur().

I am using vue & react: In my case, I can call this about anywhere between components, and it will remove the focus.

T.Woody
  • 1,142
  • 2
  • 11
  • 25
2

dummyElem.focus() where dummyElem is a hidden object (e.g. has negative zIndex)?

plodder
  • 2,304
  • 18
  • 19
1

You can call window.focus();

but moving or losing the focus is bound to interfere with anyone using the tab key to get around the page.

you could listen for keycode 13, and forego the effect if the tab key is pressed.

kennebec
  • 102,654
  • 32
  • 106
  • 127
-3

With jQuery its just: $(this).blur();

bsbak
  • 719
  • 1
  • 6
  • 18
  • 4
    This is an old answer so you may know by now, but there are two reasons this answer does not apply. 1. It assumes the OP was using jquery, 2. `this` needs to be the focused element, while the question explicitly states the OP does not know the focused element ahead of time. – Brandon Sep 27 '19 at 23:01