garson garson - 5 months ago 15
jQuery Question

Using setTimeout to temporarily change div background-color

I'm try to create an effect that loops through each of four divs and changes their color to green before changing it back to the original and moving on to the next one. Right now it is just permanently changing the colors. I'm not sure how to fix this so that the color changes back before moving on to the next one, because I am 'deleting' each prior element in order to loop properly. I'm probably doing seven things wrong, and would appreciate any advice.

Here's a working JSBin:https://jsbin.com/puricazuxa/4/edit?html,css,js,output

Javascript:

arrayCount=[1,2,3,4];
var secondPrint = function(){
setTimeout(function(){
if (arrayCount.length>0){
$("#button"+arrayCount[0]).attr("class", "sButton2");

arrayCount.shift(1);
secondPrint();
}
} ,1000);
};

secondPrint();


CSS:

body {
background-color: rgb(200,200,200);
font-family: "Arial";

}
.sButton{
height: 50px;
width: 50px;
margin: 5px;
padding: 10px;
border: 2px solid black;
display:inline;
background-color: rgb(50,100,100);
}
.sButton2{
height: 50px;
width: 50px;
margin: 5px;
padding: 10px;
border: 2px solid black;
display:inline;
background-color: rgb(100,200,100);
}


HTML:

<head>
<script src="https://code.jquery.com/jquery-3.0.0.js"></script>


</head>
<body>
<!-- Main page placeholders -->

<br/>
<br/>
<div class = "sButton" id="button1">1</div>
<div class = "sButton" id="button2">2</div>
<div class = "sButton" id="button3">3</div>
<div class = "sButton" id="button4">4</div>

Answer

Your logic is a little flawed here. A better approach would be to use setInterval() to update the state of the buttons each second, moving to the next one on each call of the function. Try this:

var secondPrint = function() {
    var $buttons = $('.sButton');
    var $active = $buttons.filter('.sButton2');
    $active = (!$active.length || $active.is(':last')) ? $('.sButton:first') : $active.next();
    $buttons.removeClass('sButton2');
    $active.addClass('sButton2');
};

setInterval(secondPrint, 1000)
secondPrint();

Example fiddle

how do I make it stop after one iteration through them all? I hadn't used setInterval() because I didn't want it to go on forever

In that case you just need to amend the logic check to clear the interval if the :last condition hits, like this:

var interval;
var secondPrint = function() {
    var $buttons = $('.sButton');
    var $active = $buttons.filter('.sButton2');
    $buttons.removeClass('sButton2');
    if ($active.is(':last')) {
        clearInterval(interval);
        return;
    }

    $active = !$active.length ? $('.sButton:first') : $active.next();
    $active.addClass('sButton2');
};

interval = setInterval(secondPrint, 1000)
secondPrint();

Updated fiddle