user940016
user940016

Reputation: 2938

Is there a way to prevent an element from losing focus in JavaScript/jQuery?

The focusout/blur events fire only after the element loses focus... By the way, I prefer to do that without using plugins.

Upvotes: 3

Views: 7522

Answers (3)

Balage1551
Balage1551

Reputation: 1067

Generally, the refocus solution works, but it fails when there is only one focusable element on the page, because the own controls of the browser is also in the tab order, and focusing on them can't be revoked.

So we need a hack to trick the browser: we should add a dummy, out-of-screen control to our page:

<div style="position: absolute; top: -100px; width: 0; height: 0; overflow: hidden;">
    <input id="__myDummyInput"/>
</div>

It is important that this control should be after the real control in tab order!

Now we could apply the code on onblur or even better on onfocuslost event:

 i.addEventListener('focusout', (e) => {
        e.preventDefault()
        if (navigator.userAgent.indexOf("Firefox") > -1) {
          setTimeout(() => e.target.focus(), 1)
        } else {
          e.target.focus()
        }
      })

Note: On Firefox the direct focus call doesn't work, so we need to add a minimal delay. However, it could produce some blinking.

Upvotes: 1

Triynko
Triynko

Reputation: 19204

Yes.

When you click on a focusable DOM element (focusable by default, or made focusable by adding the tabIndex attribute to it), then it will first receive a "focus" event to let you know that it's about to receive the focus.

Before that, however, whatever had the focus will receive a "focusout" event of type FocusEvent. Suppose your event variable is e. The e.relatedTarget property will be populated with the element that's about to receive the focus. If you handle the "focusout" event by setting the focus back to the thing that's losing the focus e.target, then it will immediately re-receive the focus, along with a "focus" and "focusin" event, while the object that was going to receive the focus will neither receive the focus nor any focus events.

Handling the "focusout" event, therefore, is the best way to prevent an object from losing the focus. Technically, because the event is not cancelable, you cannot prevent it from losing the focus, but you can force it to immediately re-receive the focus, thereby preventing the focus from being transfered to another element.

Meanwhile, if your intent is to prevent an object from receiving the focus, then you're best bet is to handle its "focus" event by calling blur on the element, so it never receives the focus nor receives a "focusin" event.

Upvotes: 4

Praveen Kumar Purushothaman
Praveen Kumar Purushothaman

Reputation: 167172

Yeah. You can use this:

<input type="text" onblur="this.focus();" />

Or in jQuery:

$(element).blur(function(){
    $(this).focus();
});

Upvotes: 4

Related Questions