Rodrixar

Tuesday, March 22

jQuery Slideshow - HTTP Efficient

Why another jQuery Slideshow Tutorial ?



A while ago I posted a tutorial on a Javascript slideshow implemented in Prototype. That was all nice and well, since there weren't a whole lot of Prototype tutorials out there. But also, the specific implementation I did was especially powerful because it had HTTP requests in mind. So now we have a version of that same slideshow in jQuery.

Live Demo:








Here's the logic behind my slideshow is simple


The usual slideshow requires that you list all of the images you want sliding in some sort of list. Then the images, through CSS, are all stacked on top of each other so only the top-most image is visible. Then, every so often the top image fades out, revealing the next one. My issue with this approach is that, suppose you have 10 images in the slideshow, all 10 images are downloaded (10 HTTP requests, bandwidth, latency, etc). Worse yet, what if the user only stays on the page long enough that only the first two images are shown?! You wasted bandwidth and loading time for the other 8 images. Not to mention if you want 100 images in the slideshow...

My approach:


I only list two images at a time. One is the top-most image (the one that's visible), and the one immediately behind it. Then, when the timer fires (the image slides), I fade the top image, reveal the back image, and wait for the next timer event to fire. When the timer gets ready to fire again, I download the next image, place it behind the current top-most image, and repeat the process. Now if the user only views my site long enough that 5 images are rotated through the slideshow, I don't have to download the remaining 95 images I wanted to display.

The Code



As this slideshow is using jQuery, the first thing we do is import the jQuery library:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>



Now we define the basic CSS so the images are self-contained:

The CSS

<style>
#iSlideShell { position: relative; height: 175px; width: 500px; overflow:hidden; }
#iSlideShell img { position: absolute; }
</style>

* note that the CSS above sets the height and width of the slideshow container, but those can be customized to your own needs.



Then we set up the HTML where the images will be displayed:

The HTML

<div id="iSlideShell">
<img id="back-image" src="image1.jpg"/>
<img id="front-image" src="image2.jpg"/>
</div>



It's very important that you keep the ID attributes of those three HTML tags as they are. If you do decide to change them, change them also in the following Javascript.

The Javascript

// keeps track of what image to display next
var i = 0;

// the time each image will display before it fades out
var delay = 3000;

// the time it will take to fade each image
var fadeDelay = 150;

// the filename for each image. Don't include the .jpg extension
var iSlides = new Array("image1", "image2", "image3", "image4", "image5");

// This is where the magic happens
function rigoSlide()
{
// show the top image
$('#front-image').show();

// make the bottom image visible
$('#back-image').show();

// after the image finishes fading, bring the back image to the front
$('#front-image').fadeOut(fadeDelay, function(){
$('#front-image').attr('src', $('#back-image').attr('src'));
});

// increment the array index, but never go beyond the array boundaries
i = (i + 1) % iSlides.length;

// now load the next image behind the image currently showing
$('#back-image').attr('src', iSlides[i] + ".jpg");

// start process over again...
setTimeout(rigoSlide, delay);

}


// call the slideshow when the page finishes loading
$(document).ready(function(){ rigoSlide(); });



Cut and Paste



Now, I realize some of you might not be able to put the above steps together all by yourself... so if that applies to you, just go ahead and paste the following block of code in your website where you want the slideshow to appear. Just make sure to replace the bold text with the names of the actual images you'll be using for your own slideshow:

<div id="jq_rigo_slide" style="width:994px; height: 300px; position: relative; top: 0; left: 0; margin: 0; padding: 0; overflow: hidden;">
<img id="jq_b" src="img1" style="position: absolute; display: block;" />
<img id="jq_f" src="img2" style="position: absolute; display: block;" />
</div>
<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js' type='text/javascript'></script>
<script type="text/javascript">
var i = 0;
var delay = 3000;
var fadeDelay = 150;
var iSlides = new Array("img1", "img2", "img3", "img4", "img5");

function rigoSlide()
{
$('#jq_f').show();
$('#jq_b').show();
$('#jq_f').fadeOut(fadeDelay, function(){
$('#jq_f').attr('src', $('#jq_b').attr('src'));
});
i = (i + 1) % iSlides.length;
$('#jq_b').attr('src', iSlides[i] + ".jpg");
setTimeout(rigoSlide, delay);
}
rigoSlide();
</script>



Conclusion


So there you have it. I'd recommend you save the Javascript externally and include it the same way you're including the jQuery Library, but that's not required for this to work.

Post your questions, comments, or concerns below.

Thanks,