41

Some thoughts are that the ELEMENT_ID.focus() is inside divs that are hidden at certain times.

This should be an easy problem to solve -- but I'm struggling :(

***code works fine -- the text field isn't being focused on upon page loading up.

STEP1 [SOLVED] JAVASCRIPT:

$("#goal-input").focus();

$('#goal-input').keypress(function(event){
 var keycode = (event.keyCode ? event.keyCode : event.which);
  if(keycode == '13') {
etc, etc, etc
}

HTML

<input type="text" id="goal-input" name="goal" />

[STEP2] JAVASCRIPT:

 if (goal) {
          step1.fadeOut('fast', function() {
          step1.hide();
          step2.fadeIn('fast');

etc, etc

HTML:

  <div id="step-2">
        <div class="notifications">
        </div>
        <input type="text" id="name"   name="name" placeholder="Name" />
               <script type="text/javascript">
              $(function(){
              $("#name").focus();
              });
            </script>

Why doesn't step 2 work? :(

dngoo
  • 499
  • 1
  • 5
  • 16
  • 6
    How about some sample code? -- According to jQuery docs on [`.focus()`](http://api.jquery.com/focus/): `Attempting to set focus to a hidden element causes an error in Internet Explorer. Take care to only use .focus() on elements that are visible. To run an element's focus event handlers without setting focus to the element, use .triggerHandler("focus") instead of .focus().` – Morgon Mar 07 '12 at 05:47
  • What do you mean "not working"? E.g., does the code run without any errors reported but the focus doesn't get set as you want, or does the browser give an error? – nnnnnn Mar 07 '12 at 05:53
  • provided sample code and what "not working" means (text field isn't focused on) @nnnnnn – dngoo Mar 07 '12 at 06:29
  • This is what you mean? http://jsfiddle.net/GyXAt/ The `#text` is never focused in on after `doc.ready`, although it apparently fires. – Jared Farrish Mar 07 '12 at 06:31
  • provided sample code above @Morgon – dngoo Mar 07 '12 at 06:32
  • Thanks @dngoo - knowing that, I recommend jgauffin's answer below. – Morgon Mar 07 '12 at 06:34
  • You probably want to use [jQuery's `event.which`](http://api.jquery.com/event.which/). – Jared Farrish Mar 07 '12 at 06:49

10 Answers10

50

I had problems triggering focus on an element (a form input) that was transitioning into the page. I found it was fixable by invoking the focus event from inside a setTimeout with no delay on it. As I understand it (from, eg. this answer), this delays the function until the current execution queue finishes, so in this case it delays the focus event until the transition has completed.

setTimeout(function(){
    $('#goal-input').focus();
});
Community
  • 1
  • 1
Nick F
  • 9,781
  • 7
  • 75
  • 90
  • I had to use a timeout of 600 before it started working, so `setTimeout(function(){ $('#goal-input').focus(); }, 600);` in the above example. – SharpC Nov 17 '16 at 12:56
  • 8
    If you're using arbitrary, trial and error-based timeout values for this sort of thing, it will almost certainly fail for some people in some contexts (ie. 600ms will be the value that happens to work for you, on your machine, on your network). It would be better to figure out why the above is not working (presumably you have other things that affect page state going on that are also getting in the way, or perhaps your setTimeout is in the wrong place). – Nick F Nov 17 '16 at 13:53
  • Thank you! This did the trick for me too when trying to focus on an element that is inside of a slideToggle-ing element. – Matt. Jul 12 '18 at 16:26
  • 1
    Thanks this is a good concept I didn't know about. I was having trouble with .focus() working sometimes but not others. This solved it for me. – squarecandy Sep 17 '18 at 09:31
  • @NickF Any luck? I'm having the same trouble but I have no idea what could be causing this really strange glitch – avisk Jul 04 '21 at 23:36
20

You need to either put the code below the HTML or load if using the document load event:

<input type="text" id="goal-input" name="goal" />
<script type="text/javascript">
$(function(){
    $("#goal-input").focus();
});
</script>

Update:

Switching divs doesn't trigger the document load event since everything already have been loaded. You need to focus it when you switch div:

if (goal) {
      step1.fadeOut('fast', function() {
          step1.hide();
          step2.fadeIn('fast', function() {  
              $("#name").focus();
          });
      });
}
jgauffin
  • 99,844
  • 45
  • 235
  • 372
  • 2
    I'd go as far to say that all DOM-related code should always go inside a DOM load handler, regardless of its relative position to its targets. :) – Morgon Mar 07 '12 at 06:34
  • This demonstrates that simply hiding and showing the parent `div` should change the `$.focus()` firing: http://jsfiddle.net/3Sz8Z/ – Jared Farrish Mar 07 '12 at 06:41
  • @Morgon: I agree. But it works to place it below the element in most browsers ;) – jgauffin Mar 07 '12 at 06:47
  • jgauffin's answer helped: it worked for my first text input. then when I apply it to the second text input, in my step 2 div, it doesn't work... (code update now) – dngoo Mar 07 '12 at 06:52
  • @jgauffin hey thanks for speedy update; I already tried that + tried it again. doesn't work o.O... -_- – dngoo Mar 07 '12 at 07:03
  • @dngoo: Read again. New change – jgauffin Mar 07 '12 at 07:32
  • @jgauffin -- thanks for the update; it seems like we're on the right track but no immediate results. will tinker later today. :) – dngoo Mar 07 '12 at 15:46
  • Yeah so it works now :) all in JS file too! The mistake: I was editing in the 'copy' file... aka wrong file... The lesson learned: use print/alert statements to see if you're editing in right file... #noobmistake THANKS EVERYONE THOUGH! I learned a lot. :) Go Stackoverflow @jgauffin – dngoo Mar 08 '12 at 06:45
  • You're a jenius!! The first line you wrote - was enough to solve my problem, thanks. – ParPar Oct 25 '12 at 11:44
9

This solved!!!

setTimeout(function(){
    $("#name").filter(':visible').focus();
}, 500);

You can adjust time accordingly.

Mohammed Rishad
  • 225
  • 3
  • 6
8

Don't forget that an input field must be visible first, thereafter you're able to focus it.

$("#elementid").show();
$("#elementid input[type=text]").focus();
n0mad
  • 320
  • 4
  • 5
4

Try something like this when you are applying focus that way if the element is hidden, it won't throw an error:

$("#elementid").filter(':visible').focus();

It may make more sense to make the element visible, though that will require code specific to your layout.

Kevin B
  • 94,570
  • 16
  • 163
  • 180
3

I found that focus does not work when trying to get a focus on a text element (such as a notice div), but does work when focusing on input fields.

Martin
  • 22,212
  • 11
  • 70
  • 132
1

Only "keyboard focusable" elements can be focused with .focus(). div aren't meant to be natively focusable. You have to add tabindex="0" attributes to it to achieve that. input, button, a etc... are natively focusable.

WegPast
  • 21
  • 4
0

The problem in my case was that I entered a value IN THE LAST NOT DISABLED ELEMENT of the site and used tab to raise the onChange-Event. After that there is no next element to get the focus, so the "browser"-Focus switches to the browser-functionality (tabs, menu, and so on) and is not any longer inside the html-content.

To understand that, place a displayed, not disabled dummy-textbox at the end of your html-code. In that you can "park" the focus for later replacing. Should work. In my case. All other tries didnt work, also the setTimeout-Version.

Checked this out for about an hour, because it made me insane :)

Mätes

Mätes
  • 1
  • 1
0

If focus() is called on TAB keypress event.preventDefault will help

I had trouble in getting focus to work when I used it inside .on('keydown') with event.keyCode == 9. I had to add a event.preventDefault to prevent the browser from tabbing again.

CORRECT CODE

$('#goal-input').on("keydown", function (event) {
    var keycode = (event.keyCode ? event.keyCode : event.which);
    if (keycode == '9') { // Keycode for TAB
        $("#name").focus();
        event.preventDefault();
    }
});

WRONG CODE !!!

$('#goal-input').on("keydown", function (event) {
    var keycode = (event.keyCode ? event.keyCode : event.which);
    if (keycode == '9') { // Keycode for TAB
        $("#name").focus();
    }
});
Sarath S Menon
  • 2,168
  • 1
  • 16
  • 21
-1

The problem is there is a JavaScript .focus and a jQuery .focus function. This call to .focus is ambiguous. So it doesn't always work. What I do is cast my jQuery object to a JavaScript object and use the JavaScript .focus. This works for me:

$("#goal-input")[0].focus();
Rodney Hickman
  • 3,133
  • 11
  • 53
  • 83