I'm trying to build a loading indicator with a image sprite and I came up with this function
function setBgPosition() { var c = 0; var numbers = [0, -120, -240, -360, -480, -600, -720]; function run() { Ext.get('common-spinner').setStyle('background-position', numbers[c++] + 'px 0px'); if (c<numbers.length) { setTimeout(run, 200); }else { setBgPosition(); } } setTimeout(run, 200); }
so the out put is looks like this
http://jsfiddle.net/TTkre/
I had to use setBgPosition(); inside else to keep this running in a loop so now my problem is how to stop this loop once I want [load finished]?
To cancel a setTimeout() method from running, you need to use the clearTimeout() method, passing the ID value returned when you call the setTimeout() method.
Working with asynchronous functions setTimeout() is an asynchronous function, meaning that the timer function will not pause execution of other functions in the functions stack. In other words, you cannot use setTimeout() to create a "pause" before the next function in the function stack fires.
Clearing setTimeout A setTimeout timer must be cleared and handle properly, otherwise, you may experience adverse side effects in your code. To clear or cancel a timer, you call the clearTimeout(); method, passing in the timer object that you created into clearTimeout().
The setTimeout() is executed only once. If you need repeated executions, use setInterval() instead.
setTimeout
returns a timer handle, which you can use to stop the timeout with clearTimeout
.
So for instance:
function setBgPosition() { var c = 0, timer = 0; var numbers = [0, -120, -240, -360, -480, -600, -720]; function run() { Ext.get('common-spinner').setStyle('background-position', numbers[c++] + 'px 0px'); if (c >= numbers.length) { c = 0; } timer = setTimeout(run, 200); } timer = setTimeout(run, 200); return stop; function stop() { if (timer) { clearTimeout(timer); timer = 0; } }
So you'd use that as:
var stop = setBgPosition(); // ...later, when you're ready to stop... stop();
Note that rather than having setBgPosition
call itself again, I've just had it set c
back to 0
. Otherwise, this wouldn't work. Also note that I've used 0
as a handle value for when the timeout isn't pending; 0
isn't a valid return value from setTimeout
so it makes a handy flag.
This is also one of the (few) places I think you'd be better off with setInterval
rather than setTimeout
. setInterval
repeats. So:
function setBgPosition() { var c = 0; var numbers = [0, -120, -240, -360, -480, -600, -720]; function run() { Ext.get('common-spinner').setStyle('background-position', numbers[c++] + 'px 0px'); if (c >= numbers.length) { c = 0; } } return setInterval(run, 200); }
Used like this:
var timer = setBgPosition(); // ...later, when you're ready to stop... clearInterval(timer);
All of the above notwithstanding, I'd want to find a way to make setBgPosition
stop things itself, by detecting that some completion condition has been satisfied.
I know this is an old question, I'd like to post my approach anyway. This way you don't have to handle the 0 trick that T. J. Crowder expained.
var keepGoing = true; function myLoop() { // ... Do something ... if(keepGoing) { setTimeout(myLoop, 1000); } } function startLoop() { keepGoing = true; myLoop(); } function stopLoop() { keepGoing = false; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With