2

The example is pretty straight forward, I am trying to change focus button after button. What I was unable to do though is to have the whole process repeating from button one when its over.

var allButtons = $(":button");
for (i = 0; i < allButtons.length; i++) {
    (function(index) {
        setTimeout(function() { 
            allButtons[index].focus(); 
        }, 1000*index);
    }(i));
}

<input type="button" value="Here" />
<input type="button" value="Here" />
<input type="button" value="Here" />
<input type="button" value="Here" />
<input type="button" value="Here" />
<input type="button" value="Here" />

input[type="button"]:focus { 
    color:red; 
}

See working example

user113716
  • 318,772
  • 63
  • 451
  • 440
topless
  • 8,069
  • 11
  • 57
  • 86

2 Answers2

6

Just use one setInterval function...

var index = -1;

setInterval(function() {
    index = (index + 1) % buttons.length;
    buttons[index].focus();
}, 1000);
6502
  • 112,025
  • 15
  • 165
  • 265
  • This will go through all the buttons once then fail when it reaches buttons.length + 1, no? – RwwL May 18 '11 at 19:22
  • Close, but you accidentally skip the first button with this implementation on the first time through. Make sure you increment `index` after you set focus, not before. – Andrew Hare May 18 '11 at 19:25
  • 1
    @RwL: He's using the mod function to prevent that - keeps the index within the length of the buttons. – Nightfirecat May 18 '11 at 19:25
  • @Nightfirecat yes, but the first `.focus()` is on `buttons[1]`, which is actually the second button after `buttons[0]` – Gabi Purcaru May 18 '11 at 19:28
  • 1
    @Andrea Hare: Fixed. I like more the idea of having `index` being the last (i.e. current) focused button in case that is needed for other events... (with `index == -1` meaning no button has been focused yet). – 6502 May 18 '11 at 19:33
1

The answer is fairly simple: Recursion. Example: http://jsfiddle.net/DduJU/

var allButtons = $(":button"),
    index = 0;
(function focus() {
    allButtons[index].focus();

    index++;
    setTimeout(focus, index*100);
    //this will be executed even though we called setTimeout
    //if index is larger than available buttons, restart it
    if (index >= allButtons.length)
        index = 0;
}());

I try to stay away from setInterval. In this example it may work fine, but setInterval will execute every n milliseconds even though the function may not complete in that time. In that case, function calls will stack. setTimeout is called here only after the major bulk of the function is complete, so even if for some reason it takes longer, you're still clear.

Zirak
  • 38,920
  • 13
  • 81
  • 92
  • 1
    Your fear is wrong... `setInterval` only schedules for calls when the execution returns to the main event loop. – 6502 May 18 '11 at 19:53