私は画像スプライトでローディングインジケータを構築しようとしていますが、この関数を思いつきました
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);
}
出力は次のようになります
SetBgPosition()を使用する必要がありました。他の内部でこれをループで実行し続けるので、私の問題は[ロード完了]が必要になったらこのループを停止する方法です。
setTimeout
は、clearTimeout
でタイムアウトを停止するために使用できるタイマーハンドルを返します。
したがって、たとえば:
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;
}
}
それを次のように使用します:
var stop = setBgPosition();
// ...later, when you're ready to stop...
stop();
setBgPosition
を再度呼び出すのではなく、c
を0
に戻すように設定したことに注意してください。そうでなければ、これは機能しません。また、タイムアウトが保留されていないときのハンドル値として0
を使用したことに注意してください。 0
はsetTimeout
からの有効な戻り値ではないため、便利なフラグを作成します。
これは、setInterval
ではなくsetTimeout
を使用した方が良いと思う(少数の)場所の1つでもあります。 setInterval
を繰り返します。そう:
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);
}
このように使用します:
var timer = setBgPosition();
// ...later, when you're ready to stop...
clearInterval(timer);
上記のすべてにもかかわらず、何らかの完了条件が満たされたことを検出することで、setBgPosition
が物事を止めるそれ自体にする方法を見つけたいと思います。
これは古い質問であることを知っています。とにかく私のアプローチを投稿したいと思います。このように、T。J. Crowderが期限切れにした0のトリックを処理する必要はありません。
var keepGoing = true;
function myLoop() {
// ... Do something ...
if(keepGoing) {
setTimeout(myLoop, 1000);
}
}
function startLoop() {
keepGoing = true;
myLoop();
}
function stopLoop() {
keepGoing = false;
}
変数を使用して「完了」を追跡し、ループの各反復でテストする必要があります。 done == trueの場合、戻ります。
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<numbers.length)
{
setTimeout(run, 200);
}else
{
setBgPosition();
}
}
setTimeout(run, 200);
}
setBgPosition(); // start the loop
setTimeout( function(){ done = true; }, 5000 ); // external event to stop 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
これはextjsタグでタグ付けされているため、extjsメソッドを見る価値があるかもしれません: http://docs.sencha.com/extjs/6.2.0/classic/Ext.Function.html#method-interval
これはsetIntervalとほぼ同じように機能しますが、スコープも考慮し、引数も渡すことができます。
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 Ext.Function.interval(run,200);
}
var bgPositionTimer = setBgPosition();
停止する場合は、clearInterval
を使用して停止できます
clearInterval(bgPositionTimer);
ユースケースの例は次のとおりです。
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);
}
});
私にはわかりませんが、あなたが望むものかもしれません:
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<=numbers.length)
{
setTimeout(run, 200);
}
else
{
Ext.get('common-spinner').setStyle('background-position', numbers[0] + 'px 0px');
}
}
setTimeout(run, 200);
}
setBgPosition();