I use jQuery cycle for lots of freelance development projects, but ran in to problems recently when building a photography site. My client was uploading around 40 high-resolution images in to a slideshow, which caused two problems:

  1. Elements using CSS background images loaded after all the img elements - meaning the navigation menu would only load after all the images had finished loading.
  2. The page took a seriously long time to finish loading.

So, I decided to fix the problem by loading each image on the fly - as soon as the cycle transition completes, it loads in the next image.

The HTML structure is as follows:


<ul id="slideshow">
    <li id="slide-1" src="/images/image1.jpg">
        <img src="/images/image1.jpg" />
    </li>
    <li id="slide-2" src="/images/image2.jpg"></li>
    <li id="slide-3" src="/images/image3.jpg"></li>
</ul>

Each img is surrounded by a list item (li), but notice how only one img is included in the HTML - all other li’s simply have a src attribute set.

The CSS simply sets the height, width and overflow:hidden (so only one image is visible, even if the client uploads images smaller than the ul dimensions:


#slideshow { width: 950px; height: 480px; overflow: hidden; }
#slideshow li { width: 100%; height: 100%; display: block; }

And finally the jQuery Cycle code:


$('#slideshow').cycle({ 
    delay: -3000, 
    timeout: 5000, 
    fx: 'fade', 
    prev: '#prev', 
    next: '#next', 
    pause: true, 
    pauseOnPagerHover: true,
    after: function(currSlideElement, nextSlideElement) {

        // Grab the ID of the next li
        var next = $(nextSlideElement).next();
        next = $('#' + next.attr('id'));

        // if the image has not already been loaded
        if (next.find('img').length == 0) {

            // create the img element and insert it in to the li
            var img = $('<img />').attr('src', next.attr('imgsrc'));
            next.append( img );
        }
    }
});
« Back