JavaScript Infinitely Looping slideshow with delays?

Here's a nice, tidy solution for you: (also see the live demo ->)

window.onload = function start() {
    slide();
}

function slide() {
    var currMarg = 0,
        contStyle = document.getElementById('container').style;
    setInterval(function() {
        currMarg = currMarg == 1800 ? 0 : currMarg + 600;
        contStyle.marginLeft = '-' + currMarg + 'px';
    }, 3000);
}

Since you are trying to learn, allow me to explain how this works.

First we declare two variables: currMarg and contStyle. currMarg is an integer that we will use to track/update what left margin the container should have. We declare it outside the actual update function (in a closure), so that it can be continuously updated/access without losing its value. contStyle is simply a convenience variable that gives us access to the containers styles without having to locate the element on each interval.

Next, we will use setInterval to establish a function which should be called every 3 seconds, until we tell it to stop (there's your infinite loop, without freezing the browser). It works exactly like setTimeout, except it happens infinitely until cancelled, instead of just happening once.

We pass an anonymous function to setInterval, which will do our work for us. The first line is:

currMarg = currMarg == 1800 ? 0 : currMarg + 600;

This is a ternary operator. It will assign currMarg the value of 0 if currMarg is equal to 1800, otherwise it will increment currMarg by 600.

With the second line, we simply assign our chosen value to containers marginLeft, and we're done!

Note: For the demo, I changed the negative values to positive, so the effect would be visible.


The correct approach is to use a single timer. Using setInterval, you can achieve what you want as follows:

window.onload = function start() {
    slide();
}
function slide() {
    var num = 0, style = document.getElementById('container').style;
    window.setInterval(function () {
        // increase by num 1, reset to 0 at 4
        num = (num + 1) % 4;

        // -600 * 1 = -600, -600 * 2 = -1200, etc 
        style.marginLeft = (-600 * num) + "px"; 
    }, 3000); // repeat forever, polling every 3 seconds
}

You don't want while(true), that will lock up your system.

What you want instead is a timeout that sets a timeout on itself, something like this:

function start() {
  // your code here
  setTimeout(start, 3000);
}

// boot up the first call
start();