Reputation: 6316
I am working on the following code. Why is the interval
happening only one time instead of 3, as expected on let x= 3
?
Basically I need to repeat this loop/interval for 3 times but it is happening only once.
$(function() {
let colors = ['red', 'blue', 'green']
let x = 3;
let interval = 6000;
for (let i = 0; i < x; i++) {
setTimeout(function() {
$('body').css('background-color', colors[i]);
backtoWhite();
}, i * interval)
}
function backtoWhite() {
setTimeout(function() {
$('body').css('background-color', 'white');
}, 3000);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Upvotes: 0
Views: 140
Reputation: 1073
Your for
loop is executing way faster than your timeout
, so you're probably only seeing the first or last iteration. When dealing with timing, I'd recommend less variables and more recursion or callbacks.
Also, I'm assuming you want the time for each color to be constant, since red
has an index of 0
and i * interval
would mean you never see red.
let colors = ['red','white','blue','white','green','white'];
function SetBackgroundColor(colorIndex) {
colorIndex = colorIndex >= colors.length - 1 ? 0 : ++colorIndex; //constrain index
$('body').css({'background-color': colors[colorIndex]}); //set color
setTimeout(
function() { SetBackgroundColor(colorIndex); }, //recursion
colors[colorIndex] === 'white' ? 3000 : 6000); //select timeout
}
SetBackgroundColor(-1); //initialize
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p></p>
Upvotes: 0
Reputation: 89324
You can use setInterval
to execute a function continuously whereas a setTimeout
executes a function once after a specified delay (in milliseconds).
The documentation for setInterval
states that:
The setInterval() method of the WindowOrWorkerGlobalScope mixin repeatedly calls a function or executes a code snippet, with a fixed time delay between each call. It returns an interval ID which uniquely identifies the interval, so you can remove it later by calling clearInterval().
The documentation for setTimeout
states that:
The setTimeout() method of the WindowOrWorkerGlobalScope mixin (and successor to window.setTimeout) sets a timer which executes a function or specified piece of code once after the timer expires.
$(function() {
let colors = ['red', 'blue', 'green']
let x = 0;
let interval = 6000;
var intvl = setInterval(function(){
$('body').css('background-color', colors[x]);
setTimeout(function(){
backtoWhite();
}, interval/2);
x++;
if(x>=3){
clearInterval(intvl);
}
}, interval);
function backtoWhite() {
$('body').css('background-color', 'white');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Upvotes: 1
Reputation: 33933
Using one interval
, the color change, cycling the color array can be done like this.
There is a white color applied in between each color change.
$(function() {
let colors = ['red', 'blue', 'green']
let index = 0;
let whiteInBetween = false; // A "flag" to toggle at each iteration to determine if to apply white instead of color.
setInterval(function() {
if(whiteInBetween){
$('body').css('background-color', "white");
}else{
$('body').css('background-color', colors[index]);
index++
}
whiteInBetween = !whiteInBetween; // "Flag" toggling
index = index%colors.length; // Keeping the color index in range, using the remainder of the index divided by the color array length
},1000); // Interval setted faster for this demo...
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body></body>
Upvotes: 0
Reputation: 4268
Based on your code structure, you can achieve what you want this way:
$(function() {
let colors = ['red', 'blue', 'green']
const nbColors = colors.length;
let repetition = 3;
let interval = 6000;
for (let loop = 0 ; loop < repetition ; loop++) {
for (let i = 0; i < nbColors; i++) {
setTimeout(function() {
$('body').css('background-color', colors[i]);
backtoWhite();
}, (i + loop * nbColors) * interval)
}
}
function backtoWhite() {
setTimeout(function() {
$('body').css('background-color', 'white');
}, interval / 2);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
But this is missing the great potential of functional programming. You should consider using callback
s to trigger the next color change once the current has finished instead of triggering all at once with different delay in execution.
Upvotes: 0