jQuery Carousel Tutorial

In this tutorial we'll create a jQuery carousel that uses some HTML5 and supports multiple carousels on the same page. We'll use the HTML5 data-* attribute to allow each carousel on the page to have independant configurable options, notably the rotation interval. If you'd like to skip the tutorial and view the final code, click here.

Before getting stuck into the tutorial, here's a demo of what we'll create:

HTML5 Markup

Demo

Let's begin by creating our HTML.

Code <ul class="cc-carousel" data-interval="3000">
    <li><a href="#1"><img src="images/beach.png" alt="Beach" /></a></li>
    <li><a href="#2"><img src="images/boats.png" alt="Boats" /></a></li>
    <li><a href="#3"><img src="images/horse.png" alt="Horse" /></a></li>
    <li><a href="#4"><img src="images/beach2.png" alt="Beach" /></a></li>
</ul>

We use the unordered list <ul> HTML tag as the container for our carousel. The list doesn't offer any functional benefits over something like nested <div> tags but it seems the most appropriate since we have a list of images. Also consider that the list will probably help in terms of accessibility.

The images and their links are hard coded into our HTML for this tutorial but it would be trivial to use a server-side script such as in PHP to populate the list from a database or other datasource. We've given the <ul> a class of cc-carousel which we'll use to identify our carousels on the page. Note the use of a class and not an ID here because we want to support multiple jQuery carousels.

The HTML5 part of this HTML is the data-interval attribute. HTML5 introduces the usage of attributes prefixed with data-. Data attributes can be used to store any information linked to the tag. Historically if we wanted to store data within the tag itself we would have done it in the ID attribute with the use of delimeters. That worked but it meant the extra work of parsing data out of the ID attribute. Especially if you were storing multiple pieces of information, it would become somewhat of a pain.

The HTML5 data attributes provide a simple solution to this problem, we can store lots of different information within the tag without having to parse it. Later in the tutorial we'll use the jQuery .data() method to retrieve the interval to rotate the images by.

The CSS

Demo

Code .cc-carousel
{
    position:relative;
    height:300px;
}

.cc-carousel li
{
    position:absolute;
    top:0;
    left:0;
    display:none;
}

We've given the container a position:relative and each of the list item's a position:absolute. The reason for this is because we want to stack all of the carousel images on top of each other at position left:0;top:0;. In order for the absolutely positioned list item's to display relative to their container, we give the container position:relative. Without that, the list item's would display in the far top left of the page instead of their container. We also set a fixed height on the container because the psoition:relative causes the container to fail to occupy space on the page. Setting dispay:none on the list item's will mean that the carousel images are hidden to start with (until our Javascript executes that is).

Base Javascript

Demo

Code var CC_Carousel = {
    nextImage : function(carousel, interval){

    }
};

$(document).ready(function(){
    $('.cc-carousel').each(function(){

    });
});

The first thing we'll do with Javascript is include the jQuery library itself. For this tutorial I'll use the 1.9.1 version hosted on the CDN. Considering we want to support multiple jQuery carousels, some sort of object that will manage the carousels without duplicating code seems like a good starting place. We have a CC_Carousel object literal which has a method nextImage(). We'll use this to handle all of the rotating banner/carousel functionality. The nextImage() method accepts a carousel argument which will be the carousel object (or <ul> DOM node). It also accepts an interval argument which will be the length of time between rotations. It's important that we accept the carousel object as an argument at this point in order to support multiple jQuery carousels. So far the method doesn't do anything else.

Looking at the $(document).ready() part of code, for those that don't know, this is a jQuery specific method of running our code only when the page is loaded and ready. The .each() line is looping through all jQuery carousels on the page - again necessary to support multiple carousels.

Add carousel/rotating banner code

Demo

Code var CC_Carousel = {
    nextImage : function(carousel, interval){
        var next;
        
        if($(carousel).find('.cc-carousel-active').length == 0){
            next = $(carousel).find('> li').first();
        } else {
            var previous = $(carousel).find('.cc-carousel-active');
            previous.removeClass('cc-carousel-active');
            
            next = previous.next().length == 1 ? previous.next() :
                $(carousel).find('> li').first();
            
            previous.hide();
        }
        
        next.addClass('cc-carousel-active');
        next.show();
        
        setTimeout(function(){
            CC_Carousel.nextImage(carousel, interval);
        }, interval);
    }
};

$(document).ready(function(){
    $('.cc-carousel').each(function(){
    
        var interval = $(this).data('interval');
        CC_Carousel.nextImage(this, interval);

    });
});

Lets look at the content of the nextImage() method on the CC_Carousel object. In a nutshell, the purpose of this function is to accept a carousel object and interval as arguments, hide the current image, show the next image and then set up a timer to call itself over and over.

The first thing we need to know is is there any current image, or has the page just loaded and we're not showing any image yet? We need some way of tracking which image is being displayed at the currrent time. For this we'll assign a class cc-carousel-active to the active list item.

To determine if there is an image currently showing, we can simply use a jQuery selector that looks for the active class. The first if statement does this. By using the find() method, we can narrow the search for the active class to within the carousel object in question, so that we don't affect other carousels. By checking the length of the matched elements, we can see if there are any active images. In the if statement block, we know that there are no active images, so we need to have the first image shown immediately. To grab a handle on the first image within the carousel we'll use the selector > li which will match all list item's that are a direct child of the carousel. Then we use jQuery's .first() method which will reduce the matched element list to the first element matched. Altenatively we could have used the jQuery .eq(0) method which would also match the first element in the list.

The else block will execute if there is already an active image. In this case we need to hide the current active image, then get a handle on the next image in line. The first thing we do is grab the currently active image and store it in a previous variable. We then remove the active class from the currently active image. Next we need to do something a bit more tricky. We need to get a handle on what should be the next image to show. For that we'll use jQuery's next() method which matches the next sibling of the element. It's not quite as simple as that though, consider what will happen when we get to the final image in the list. We need some way of checking if there is actually a next list item, or if we're at the end of the list, in which case we would want to start again at the beginning of the list so that the jQuery carousel continues to cycle.

To do that we'll use the ternary operator to make the code a bit more elegant. The ternary operator is simple a shorthand if/else statement. By checking the length of the jQuery next() method, we can determine if we're at the end of the list and so need to restart, or if there's a next sibling. Our ternary operator is saying: if there's a next sibling, set the variable next to it, or if not then set the next variable to the first list item.

After the if block we show the first list item and then we set up a timer to fire our function which creates recursion because our function calls itself. To create a timer, we use the setTimeout() Javascript function. This function accepts a function as an argument, which it will execute when the specified period of time expired. We set the expiry time to our interval variable, which is an amount of milliseconds (1000ms = 1 second). Within the function to execute, we simply make a call to our nextImage() function, passing in the carousel and interval so that the process can repeat itself after the interval.

We've covered the code to do the actual image switching, now all that's left is to link this with our .each() function within the $(document).ready() call. At this point, we grab the interval then call CC_Carousel.nextImage() function, passing in this and the interval. Within jQuery's .each() function, this refers to the current element, in our case the carousel container.

If you run the code so far, you'll see a working jQuery carousel. You'll probably notice it doesn't look as flashy as some other carousel's that you may have seen. In the next part we'll add some fading animation to make the rotation transition nicer.

Fade animation and final code

Demo

Code var CC_Carousel = {
    nextImage : function(carousel, interval){
        var next;
        
        if($(carousel).find('.cc-carousel-active').length == 0){
            next = $(carousel).find('> li').first();
            next.show();
        } else {
            var previous = $(carousel).find('.cc-carousel-active');
            previous.removeClass('cc-carousel-active');
            
            next = previous.next().length == 1 ? previous.next() :
                $(carousel).find('> li').first();

            previous.fadeOut();
            next.fadeIn();
        }
        
        next.addClass('cc-carousel-active');
        
        setTimeout(function(){
            CC_Carousel.nextImage(carousel, interval);
        }, interval);
    }
};

$(document).ready(function(){
    $('.cc-carousel').each(function(){
    
        var interval = $(this).data('interval');
        CC_Carousel.nextImage(this, interval);

    });
});

We can make our carousel look better by adding a transitional fading effect between the image rotation. There's a few changes required to do this. Within our nextImage() function's else block, we've added a fade out and fade in of the previous and next elements respectively. .fadeOut() and .fadeIn() are built in methods of jQuery. Because .fadeIn() does the equivelent of .show() on completion, we no longer need to call .show() after adding the active class. Since we have removed the .show() call from after the if block, we need to move it to inside the if block because otherwise on the first load, the first image would not be shown. Similarly, .fadeOut() will hide the element on completed, so we no longer need the previous.hide() call.

Multiple instances

Demo

Code <h3>First Carousel - 3 second interval</h3>
<ul class="cc-carousel" data-interval="3000">
    <li><a href="#1"><img src="images/beach.png" alt="Beach" /></a></li>
    <li><a href="#2"><img src="images/boats.png" alt="Boats" /></a></li>
    <li><a href="#3"><img src="images/horse.png" alt="Horse" /></a></li>
    <li><a href="#4"><img src="images/beach2.png" alt="Beach" /></a></li>
</ul>

<h3>Second Carousel - 1.5 second interval</h3>
<ul class="cc-carousel" data-interval="1500">
    <li><a href="#1"><img src="images/beach.png" alt="Beach" /></a></li>
    <li><a href="#2"><img src="images/boats.png" alt="Boats" /></a></li>
    <li><a href="#3"><img src="images/horse.png" alt="Horse" /></a></li>
    <li><a href="#4"><img src="images/beach2.png" alt="Beach" /></a></li>
</ul>

I wrote about making our carousel support multiple carousels on the same page. To make another jQuery carousel on the same page, all we need to do is duplicate the HTML and change the images and set the interval as desired.

To conclude, I hope this tutorial has helped to demonstrate how we can leverage jQuery's DOM manipulation and HTML5 and a bit of plain old Javascript to create a nice looking jQuery carousel.

Comments

There are 0 responses. Why not add a comment? No registration required.

Leave a Comment

Enter Code

Refresh code

Menu

Firefox Addons