可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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
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]?
回答1:
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.
回答2:
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; }
回答3:
You need to use a variable to track "doneness" and then test it on every iteration of the loop. If done == true then return.
var done = false; function setBgPosition() { if ( done ) return; var c = 0; var numbers = [0, -120, -240, -360, -480, -600, -720]; function run() { if ( done ) return; Ext.get('common-spinner').setStyle('background-position', numbers[c++] + 'px 0px'); if (c
回答4:
As this is tagged with the extjs tag it may be worth looking at the extjs method: http://docs.sencha.com/extjs/6.2.0/classic/Ext.Function.html#method-interval
This works much like setInterval, but also takes care of the scope, and allows arguments to be passed too:
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
when you want to stop you can use clearInterval
to stop it
clearInterval(bgPositionTimer);
An example use case would be:
Ext.Ajax.request({ url: 'example.json', success: function(response, opts) { clearInterval(bgPositionTimer); }, failure: function(response, opts) { console.log('server-side failure with status code ' + response.status); clearInterval(bgPositionTimer); } });
回答5:
SIMPLIEST WAY TO HANDLE TIMEOUT LOOP
function myFunc (terminator = false) { if(terminator) { clearTimeout(timeOutVar); } else { // do something timeOutVar = setTimeout(function(){myFunc();}, 1000); } } myFunc(true); // -> start loop myFunc(false); // -> end loop
回答6:
I am not sure, but might be what you want:
var c = 0; function setBgPosition() { var numbers = [0, -120, -240, -360, -480, -600, -720]; function run() { Ext.get('common-spinner').setStyle('background-position', numbers[c++] + 'px 0px'); if (c