Adventures in creating a javascript image carousel or slideshow; a simple tutorial

Jun 14 2015

👉 Here’s the carousel

Javascript image slideshows or carousels are easy to find on the internet. In fact, you could argue that they are a solved problem and rolling your own is rather pointless. If you are using one of the more popular css frameworks such as Bootstrap or Foundation, you’ll already have an image slider/image carousel included in the framework’s javascript.

Why then, should you try your hand at coding your own?

Kitchen sink

Most carousels have everything but the kitchen sink. Navigation arrows, captions, keyboard support, slide numbers, slide bullets, play button, pause button, forward button, backward button, transition options, timer options…the list goes on. Infinitely customisable carousels are great, but they come with a cost; time spent learning to use them.

Sometimes you really just need a barebones carousel. Something that does nothing more than flip between an array of images. No configuration. No options. No problem.

Dependencies

We are going to lean on jQuery.

Some basic markup

We need some minimal markup for our carousel. A container div if you will. About as simple as I can think is as follows:

<div id="carousel">
</div>

Make the id unique within your own DOM.

It’s a common pattern in carousels to place each image in it’s own container element - often an li or a div. For this example, I’m going to use div elements as my image containers. Expand your markup to look like this:

<div id="carousel">
    <div class="carouselImage">
        <img src="images/images1.jpg">
    </div>
    <div class="carouselImage">
        <img src="images/images2.jpg">
    </div>
    <div class="carouselImage">
        <img src="images/images3.jpg">
    </div>
</div>

You’ll need three images obviously. I’m using some I found on picture of the day.

There are several ways of creating the actual carousel/slideshow effect. One way is to position the three inner divs absolutely in their container element at top and left of 0, 0. In this way, the images are directly on top of each other. To give a carousel effect, show one image at a time, hiding the others. This works well.

A different approach is to position the divs next to each other within their container, ensure the container has overflow:hidden and adjust the left offset of the container to bring images into and out of view. This panorama approach trades managing visibility for managing position. This also works well.

We will work with the first approach, for no particular reason.

Javascript

Our Javascript’s task is to control which image is on display. To do this, we will toggle a class on the relevant carouselImage element. Our jQuery work starts off setting this class (let’s call it active) against our first image:

$(function() {
    $('.carouselImage').first().addClass('active');
});

All good carousels need a timer. Javascript provides the setInterval function to help us create an event that fires at specified intervals. We will start off with once every five seconds. Append the following to your code from above:

setInterval(function() {
    },5000);
});

Now we need to toggle the active class of two images - we need the next image in the list to become active and we need to remove the active class from our current image. The added complexity here is if our current image is the last image in the set, we need to loop back round to the first image. Here’s the code we need:

setInterval(function() {
        $currentImage = $('.carouselImage.active');
        $nextImage = $currentImage.next();

        // if our current image is the last in our group of images,
        //  our next image will not exist
        if($nextImage.length === 0) {
            $nextImage = $('.carouselImage').first();
        }
        $currentImage.removeClass('active');
        $nextImage.addClass('active');
    },5000);
});

We start by finding our currently selected image and stashing it in a variable $currentImage. The first time we hit this it should be our first carouselImage element because we explicitly set it to be active earlier. Then we use jQuery’s next() function to select the next sibling of our current image. jQuery’s next() will try to find the next element sitting at the same hierarchical level of the DOM. In our case we have three siblings at the carouselImage level of the DOM.

To determine whether or not we are displaying the last of our images, we need to test that there really is a next sibling. In jQuery, we do this by testing the length of the object we’ve tried to find. If the length is 0, we have no object and in our code, that means our current active carouselImage is the last one. Although in the above code, I’m explicitly testing for $nextImage.length === 0, you’ll quite often see this code as !$nextImage.length because in Javascript, 0 is a falsy value. Inside our if statement, we use the handy first() function to select the first carouselImage element, just as we did earlier.

The final two lines of code simply remove the active class from our currently active carouselImage element and add the active class to the next carouselImage element we want to become visible.

If you run this code now, nothing will happen because we still haven’t put any styling together. I say nothing, but if you pull up the developer tools on your browser, you can watch the active class being set and removed against the carouselImage elements.

Developer tools showing looping active element {: .center-block}

Style

All that remains now, is to set some styling.

<style>
   .carouselImage {
        position: absolute;
        left: 0;
        top: 0;
        display: none;
    }
    .carouselImage.active {
        display: block;
    }
</style>

Great - we set each .carouselImage to sit at the top left of its container element. Then we make sure they are hidden by setting display to none. We could use visibility instead of display, but setting the visibility of an item keeps it’s position in the layout. Setting display to none actually removes the item from the layout so it essentially takes no space. The .active class simply sets the display to block so that the element is shown.

Credits

Images grabbed from the wonderful Wikimedia image of the day archives.