Callum
Callum

Reputation: 77

JavaScript: Last setInterval lasts longer then expected

I asked for help before on how to fix something with my javascript code, I have that fixed now however is there a problem with my code? Because the last array stays on for longer than 1 second, it stays on for like 5 seconds. Is this because I'm resetting the array or is this normal in Javascript?

function Background()
{
    var Backgrounds = [
        '#333', '#777', '#999', '#CCC'
    ],
    Max_Backgrounds = Backgrounds.length, 
    Background_Stage = -1;// Yes, it's meant to be -1 so when background_stage++; is called it will make it 0 thus start at the beginning of the array.
    setInterval(function() { 
        if(Background_Stage >= Max_Backgrounds) Background_Stage = -1;
            $('body').css('background', Backgrounds[Background_Stage++]); 
    }, 1000);
}

Upvotes: 1

Views: 118

Answers (3)

ckal
ckal

Reputation: 3570

$('body').css('background', Backgrounds[Background_Stage++]);

is equivalent to

$('body').css('background', Backgrounds[Background_Stage]);
Background_Stage = Background_Stage + 1;

Each time around the loop, the background is getting set to undefined. If you want to have your variable increment before being accessed you would need to use

$('body').css('background', Backgrounds[++Background_Stage]);

full example (if condition was also modified):

function Background()
{
    var Backgrounds = [
        '#333', '#777', '#999', '#CCC'
    ],
    Max_Backgrounds = Backgrounds.length, 
    Background_Stage = -1;// Yes, it's meant to be -1 so when background_stage++; is called it will make it 0 thus start at the beginning of the array.
    setInterval(function() { 
        if(Background_Stage >= Max_Backgrounds - 1) Background_Stage = -1;
            $('body').css('background', Backgrounds[++Background_Stage]); 
    }, 1000);
}

Upvotes: 0

Robert Byrne
Robert Byrne

Reputation: 560

As pointed out in the comments, you are not changing the background in the last iteration, which is why it lingers for longer than the others, this should keep it consistent

working example: http://jsfiddle.net/uRSC5/

function background() {
    var backgrounds = [
        /*"./../../Styles/Callum_Project1/Images/Background_1",
        "./../../Styles/Callum_Project1/Images/Background_2",
        "./../../Styles/Callum_Project1/Images/Background_3"*/
        '#333', '#777', '#999', '#CCC'
    ];

    var count = backgrounds.length;
    var i = 0;

    setInterval(function() { 
        $('body').css('background', backgrounds[i++]); 
        if(i >= count) i = 0;
    }, 1000);
}

$(background);

Upvotes: 2

Roger
Roger

Reputation: 2952

I'd suggest not doing the -1 initialization and use rather the module. i.e. 3 % 2 == 1 which yields the remainder of a division.

http://jsfiddle.net/KtsHa/1/

(function Background () {
    var Backgrounds = [
        '#333', '#777', '#999', '#CCC'
    ],
    Max_Backgrounds = Backgrounds.length, 
    Background_Stage = 0,
    changeBackground = function () {
        $('body').css('background', Backgrounds[Background_Stage]); 
        Background_Stage = (Background_Stage + 1) % Max_Backgrounds;                
    };
    changeBackground(); // Remove this line if what you intend is to wait one second before the first change
    setInterval(changeBackground, 1000);
}());

Also, setInterval is known to drift, so I'd rather use setTimeout and do it again 1 second later: http://jsfiddle.net/KtsHa/2/

(function () {
    var Backgrounds = [
        '#333', '#777', '#999', '#CCC'
    ],
    Max_Backgrounds = Backgrounds.length, 
    Background_Stage = 0,
    changeBackground = function () {
        $('body').css('background', Backgrounds[Background_Stage]); 
        Background_Stage = (Background_Stage + 1) % Max_Backgrounds;
        setTimeout(changeBackground, 1000);
    };
    changeBackground();
}());

Upvotes: 0

Related Questions