J'essaie de construire un indicateur de chargement avec une image Sprite et je suis venu avec cette fonction
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);
}
de sorte que la sortie est ressemble à ceci
Je devais utiliser setBgPosition (); à l’intérieur d’autre chose pour que cela continue dans une boucle, alors maintenant, mon problème est de savoir comment arrêter cette boucle quand je veux [chargement terminé]
setTimeout
renvoie un descripteur de minuterie, que vous pouvez utiliser pour arrêter le délai avec clearTimeout
.
Donc par exemple:
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;
}
}
Donc, vous utiliseriez cela comme:
var stop = setBgPosition();
// ...later, when you're ready to stop...
stop();
Notez que plutôt que d'avoir setBgPosition
à appeler de nouveau lui-même, je viens juste de le redéfinir à c
sur 0
. Sinon, ça ne marcherait pas. Notez également que j'ai utilisé 0
en tant que valeur de descripteur lorsque le délai d'attente n'est pas en attente. 0
n'est pas une valeur de retour valide de setTimeout
et constitue donc un indicateur pratique.
C’est aussi l’un des (rares) endroits où je pense qu’il serait préférable d’utiliser setInterval
plutôt que setTimeout
. setInterval
répète. Alors:
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);
}
Utilisé comme ceci:
var timer = setBgPosition();
// ...later, when you're ready to stop...
clearInterval(timer);
En dépit de tout ce qui précède, j'aimerais trouver un moyen de rendre setBgPosition
arrêter les choses lui-même , en détectant qu'une condition d'achèvement a été remplie.
Je sais que c'est une vieille question, j'aimerais quand même poster mon approche. De cette façon, vous n'avez pas à gérer le truc 0 que T. J. Crowder a expliqué.
var keepGoing = true;
function myLoop() {
// ... Do something ...
if(keepGoing) {
setTimeout(myLoop, 1000);
}
}
function startLoop() {
keepGoing = true;
myLoop();
}
function stopLoop() {
keepGoing = false;
}
Vous devez utiliser une variable pour suivre le "rendu", puis la tester à chaque itération de la boucle. Si c'est fait == vrai, alors retourne.
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
LA MANIÈRE LA PLUS SIMPLE DE GÉRER LA BOUCLE TIMEOUT
function myFunc (terminator = false) {
if(terminator) {
clearTimeout(timeOutVar);
} else {
// do something
timeOutVar = setTimeout(function(){myFunc();}, 1000);
}
}
myFunc(true); // -> start loop
myFunc(false); // -> end loop
Comme ceci est étiqueté avec la balise extjs, il peut être intéressant de regarder la méthode extjs: http://docs.sencha.com/extjs/6.2.0/classic/Ext.Function.html#method-interval
Cela fonctionne beaucoup comme setInterval, mais prend également en charge la portée, et permet également de transmettre des arguments:
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();
quand vous voulez arrêter, vous pouvez utiliser clearInterval
pour l'arrêter
clearInterval(bgPositionTimer);
Un exemple de cas d'utilisation serait:
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);
}
});
Je ne suis pas sûr, mais c'est peut-être ce que vous voulez:
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();