27

How to keep the Focus on one textbox ? even if you click anywhere in a browser.

$("#txtSearch").focus();
Konstantin Dinev
  • 34,219
  • 14
  • 75
  • 100
Bonesh
  • 817
  • 2
  • 10
  • 17

7 Answers7

32

You need to subscribe to the blur event of the textbox and reinstate focus with a small timeout:

$('#txtSearch').blur(function (event) {
    setTimeout(function () { $("#txtSearch").focus(); }, 20);
});

This way you don't rely on subscribing to the events of any other element on the page. If you subscribe to body click or html click, it won't run if any other element prevents propagation of its click event, also it won't work when tabbing out of the textbox.

Example:

<!-- I will not propagate my click to top level DOM elements -->
<button id="button">Click me</button>

<script>
$('#button').click(function (event) {
    event.stopPropagation();
});
</script>
Konstantin Dinev
  • 34,219
  • 14
  • 75
  • 100
  • +1 this is the only answer so far that handles events like tabbing out of focus. – David Hedlund Apr 16 '13 at 13:54
  • Blur is the event that fires when the focus has been lost on an element – lucuma Apr 16 '13 at 13:54
  • 1
    @Curt I included some explanation on why not to handle click. – Konstantin Dinev Apr 16 '13 at 13:55
  • +1 My answer doesn't taken into account tabbing, other click events etc. – Curtis Apr 16 '13 at 13:55
  • Why the timeout, out of interest? – LeonardChallis Apr 16 '13 at 13:57
  • @LeonardChallis Because otherwise focus would not work. I can't quite explain why :( – Konstantin Dinev Apr 16 '13 at 14:00
  • 1
    @LeonardChallis : if you don't timeout, the `$("#txtSearch").focus()` will instantly (and synchronously) be applied, then the `blur` event will bubble up the tree, and the textarea will lose the focus. – LeGEC Apr 16 '13 at 14:00
  • AFAIK, the timeout could as well be 0, though. The important part is to apply the function *after* the `blur` event has been completely resolved. – LeGEC Apr 16 '13 at 14:03
  • @LeGEC Since when do the `blur` or `focus` events bubble? Your example is exactly why they don't. – Ian Apr 16 '13 at 14:03
  • The only reason is for this to run "async", not in the event handler. I have used it often and it's funny that I can't explain why it works this way. – Konstantin Dinev Apr 16 '13 at 14:06
  • @LeGEC You're just contradicting yourself. `blur` doesn't bubble. `focusout` does - http://api.jquery.com/focusout/ . Here's an example - http://jsfiddle.net/6g68C/ – Ian Apr 16 '13 at 14:08
  • @Ian : I stand corrected. I have used jQuery event delegation on `blur`, so I thought the event behaved as other regular events. The last parahraph in http://api.jquery.com/blur/ mentions only Internet Explorer, so I thought it was yet another special case for IE. – LeGEC Apr 16 '13 at 14:15
  • @LeGEC Yeah, it's put together very confusingly. I'm betting jQuery takes care of things internally so that it makes all events "bubble", but only fires certain things if they're bound a certain way. So with your example of event delegation, when it's "bubbling" internally, it checks the event handler and sees it's delegated, so it should be executed. Something like that. – Ian Apr 16 '13 at 14:19
  • I know IE (or at least old IE) has problems with focusing the element without `setTimeout`, or at least I thought it did, and that's why I always use it. I can't find the resource I "learned" it from, but I know I wouldn't use it that way if I didn't see something like that about it – Ian Apr 16 '13 at 14:21
  • @Ian : the api doc (http://api.jquery.com/blur/) says it actually binds a listener to `focusout` when you delegate `blur` handling. – LeGEC Apr 16 '13 at 14:26
  • 2
    I always solve this like so -> [**FIDDLE**](http://jsfiddle.net/QhaLY/1/), and find it more "proper" ??? – adeneo Apr 16 '13 at 14:27
  • @LeGEC Psh all I needed to do was read. Well that's interesting...makes sense though – Ian Apr 16 '13 at 14:29
  • @adeneo That's nifty! Unfortunately, you can still tab away. But as for clicking, that's cool – Ian Apr 16 '13 at 14:36
9

Konstantin Dinev answer works ok in most cases, but if you dont want to lose the focus only when clicking on certain parts of the html just do this:

$(".nofocus").on( "mousedown", function (e) {
    return false;
});

In my case i'm doing a small html text editor and i dont want to lose the control when pressing an action button, but yes in any other case.

I just need to add the nofocus class to the button and it will not take the control

Hamboy75
  • 938
  • 1
  • 11
  • 22
  • 1
    Thank you! This is the ideal answer. This solution prevents the loss of focus in the first place. This is what you need if you want to manipulate `selectionStart` of a textarea. All the other answers describe how to return focus immediately after losing focus. – noamyg Jul 19 '20 at 11:24
  • 1
    For me, this does the opposite. It prevents me from focusing... – code May 16 '21 at 05:19
  • For me, I had to call `e.preventDefault()` to prevent losing focus, `return false` didn't seem to do anything. https://codepen.io/TechnoSam/pen/ZEyxxvy – TechnoSam Sep 19 '21 at 15:12
3
$("html").click(function(){
   $("#txtSearch").focus();
});

Live Demo: http://jsfiddle.net/QhaLY/

Curtis
  • 101,612
  • 66
  • 270
  • 352
3

It's also possible without jQuery and without re-focusing, if you just need a click on specific elements to not grab the focus

just listen for the mousedown event and cancel it

element.addEventListener("mousedown", event => {event.preventDefault(); event.stopPropagation()});
1
$('body').click(function(){$("#txtSearch").focus();});
user1032531
  • 24,767
  • 68
  • 217
  • 387
0

There are other ways of loosing focus than clicking area away from the input i.e. tabbing. If you want to prevent loosing focus use blur event i.e.

document.getElementById('txtSearch').addEventListener('blur', e => {
  e.target.focus();
});
Alan Bogu
  • 705
  • 5
  • 9
0

I use onMouseDown={e => e.preventDefault()} and that works just fine.

Stroga
  • 1
  • 2