jQuery Photo Slide Show with Slick Caption Tutorial Revisited

Written by Kevin Liew on 16 Dec 2009
266,256 Views • Tutorials

Introduction

If you have been reading my website from the start you would have read this tutorial:

Simple jQuery Image Slide Show with Semi Transparent Caption

It's a very famous post because it has been showcased in several major web design blogs so many times and I received a lot of traffic from it. Thanks guys. I get a lot of comment and as I replied to those comments and do some quick fixes, I realized that this script has a caption bug and inefficient and not up to standard (oh well, that's the time when I was start picking up jQuery :)), so I have decided to do revisit to solve all those problems discovered by readers. I rewrote the html structure and modify the script.

Mission Objectives:

  • Restructure the HTML, more semantic
  • Fix the caption bug, it displays the next caption too fast
  • W3C standard compliant, using appropriate attribute to store title and description
  • Cross Browser - Chrome, Safari, IE6, 7, 8 and Firefox.

However, one thing though, it needs javascript, if your browser is javascript disabled, sorry, there is no graceful degradation for this script, it will just display the first item.

Advertisement

1. HTML

Yes, I'm using list this time :) This is how it should have been afterall. No more REL attribute, we wil be using TITLE Attribute to store the heading and ALT attribute to store the description. For the caption elements, it will be added using jQuery. So, this is it - a clean and simple HTML code.

<ul class="slideshow">
	<li class="show"><a href="#"><img data-src="images/s1.gif" width="450" height="200" title="Slide 1" alt="Short Description"/></a></li>
	<li><a href="#"><img data-src="images/s2.gif" width="450" height="200" title="Slide 2" alt="Short Description"/></a></li>
	<li><a href="#"><img data-src="images/s3.gif" width="450" height="200" title="Slide 3" alt="Short Description"/></a></li>
</ul>

2. CSS

CSS code is rewritten completely. I guarantee it's cross browser compliant. They all look identical and it works great :) I did learn a lot of CSS technique through this blog. We all can improve our skills through tips, tricks, trials and errors. Read these posts to learn more about CSS:

body {
	font-family:arial;	
	font-size:12px;
}

ul.slideshow {
	list-style:none;
	width:450px;
	height:200px;
	overflow:hidden;
	position:relative;
	margin:0;
	padding:0;
	
}	

ul.slideshow li {
	position:absolute;
	left:0;
	right:0;
}

ul.slideshow li.show {
	z-index:500;	
}

ul img {
	border:none;	
}

#slideshow-caption {
	width:450px;
	height:70px;
	position:absolute;
	bottom:0;
	left:0;	
	color:#fff;
	background:#000;
	z-index:500;
}

#slideshow-caption .slideshow-caption-container {
	padding:5px 10px;	
	z-index:1000;	
}

#slideshow-caption h3 {
	margin:0;
	padding:0;	
	font-size:14px;
}

#slideshow-caption p {
	margin:5px 0 0 0;
	padding:0;
}

3. Javascript

We will going to use call back function to display caption. This will solve the "Caption Is Appearing Before The Next Slide Syndrome" :). Not too much of changes in javascript but I do added a feature though. On mouse over the slide will pause, and resume it back on mouse out. I think it's a good touch.

$(document).ready(function() {		
	
	//Execute the slideShow, set 4 seconds for each images
	slideShow(2000);

});

function slideShow(speed) {


	//append a LI item to the UL list for displaying caption
	$('ul.slideshow').append('
  •  
'); //Set the opacity of all images to 0 $('ul.slideshow li').css({opacity: 0.0}); //Get the first image and display it (set it to full opacity) $('ul.slideshow li:first').css({opacity: 1.0}).addClass('show'); //Get the caption of the first image from REL attribute and display it $('#slideshow-caption h3').html($('ul.slideshow li.show').find('img').attr('title')); $('#slideshow-caption p').html($('ul.slideshow li.show').find('img').attr('alt')); //Display the caption $('#slideshow-caption').css({opacity: 0.7, bottom:0}); //Call the gallery function to run the slideshow var timer = setInterval('gallery()',speed); //pause the slideshow on mouse over $('ul.slideshow').hover( function () { clearInterval(timer); }, function () { timer = setInterval('gallery()',speed); } ); } function gallery() { //if no IMGs have the show class, grab the first image var current = ($('ul.slideshow li.show')? $('ul.slideshow li.show') : $('#ul.slideshow li:first')); //trying to avoid speed issue if(current.queue('fx').length == 0) { //Get next image, if it reached the end of the slideshow, rotate it back to the first image var next = ((current.next().length) ? ((current.next().attr('id') == 'slideshow-caption')? $('ul.slideshow li:first') :current.next()) : $('ul.slideshow li:first')); //Get next image caption var title = next.find('img').attr('title'); var desc = next.find('img').attr('alt'); //Set the fade in effect for the next image, show class has higher z-index next.css({opacity: 0.0}).addClass('show').animate({opacity: 1.0}, 1000); //Hide the caption first, and then set and display the caption $('#slideshow-caption').slideToggle(300, function () { $('#slideshow-caption h3').html(title); $('#slideshow-caption p').html(desc); $('#slideshow-caption').slideToggle(500); }); //Hide the current image current.animate({opacity: 0.0}, 1000).removeClass('show'); } }

Updates

2010-09-10: Thanks to Rezzie who nailed the IE8 issue! :)

Updated the article and scripts, the link issue is fixed. :) Sorry for the delay.

Speed Issue

This is one of the issue that has been haunted me for a while, but thanks to Sam, one of our reader, he pointed out this would solve the issue, but with mixed result in IE.

Sam's solution, you need to add this:

$(window).focus(function () {
	timer = setInterval('gallery()', speed); 
});
$(window).blur(function () {
	clearInterval(timer);
});

James Burnett's solution, you modify the gallery function():

function gallery() {
	var current = ($('ul.slideshow li.show')? $('ul.slideshow li.show') : $('#ul.slideshow li:first'));

	if(current.queue('fx').length == 0) {
		
		// grab next image and animate code in here
		......
		......
		......
		
	}
}

Also, did some research, found the reason why it's doing it: From jQuery Animate Documentation: Because of the nature of requestAnimationFrame(), you should never queue animations using a setInterval or setTimeout loop. In order to preserve CPU resources, browsers that support requestAnimationFrame will not update animations when the window/tab is not displayed. If you continue to queue animations via setInterval or setTimeout while animation is paused, all of the queued animations will begin playing when the window/tab regains focus. To avoid this potential problem, use the callback of your last animation in the loop, or append a function to the elements .queue() to set the timeout to start the next animation.

Sorry guys, I don't have time to put all these together. Please let me know it works.

Randomize Slides

Simple yet effective solution from another reader - Blastos

Before the ending of function slideShow(), put this in:

//Generate a random number
var randNum = Math.floor(Math.random() * $('ul.slideshow li').length);

//Randomly pick up a slide
$('ul.slideshow li:eq('+randNum+')').addClass('show');

Caption doesn't appear for the first slide

I think it has to be the ommitted A tag for some users. Ammended the script, it should be fixed now.

Conclusion

I have made a lot of tutorials, and I think it's good to do a revisit to make it more efficient and solve some of the annoying bugs instead of quick fixes. So, yea, from now on, I will check my previous tutorials and rewrite them. :)

Like this tutorials? You can express your gratitude by visiting my sponsors on the sidebar, bookmark it and help me to spread this tutorial to our friends! :) Thanks!

Demo Download
Join the discussion

Comments will be moderated and rel="nofollow" will be added to all links. You can wrap your coding with [code][/code] to make use of built-in syntax highlighter.

488 comments
Neil 15 years ago
Hi There, Very helpful tutorial!

I'm trying to use this slideshow on a content page on a wordpress site. I'm getting a "Cannot call method 'append' of Null" error trying to append the li to the ul. Any ideas?

Thanks,
Neil.
Reply
Kevin Liew Admin 15 years ago
Okay, I think you need to make sure jQuery framework is installed properly.
Reply
Lisa Edwards 15 years ago
Thanks for a great slideshow! I'm running into a couple of problems I'm hoping you can help with.

I have 3 slideshows on our new home page and I'm getting some weird results. The "websites" & "video" slides are not starting at the same time as the "3d" slides. They also completely stop as the "3d" slides continue to play. I do want them all to continue to loop. I thought it might be because the other 2 had different # of slides but even with the same number of slides it doesn't work properly. Any thoughts on what might be causing this and how I can fix it? Here is the link to the page: http://www.monkeywrenchstudio.com/home.html Thank you!
Reply
Steve 15 years ago
Hi, Great script. Can you inlcude the caption as part of the link like the rest of the image?
Reply
Sam 15 years ago
Hi, firstly thanks for the script! Simple.. love it. Although I'm not sure if I've found a bug.

When using chrome (sometimes firefox) if i leave the page open on another tab, then go back to it, the slideshow goes crazy! the transition timing goes from 5seconds to instant and it loops through as though its trying to "catch up" on restore. Then it slowly stops... then goes back to normal.

I bet its doing it now, so I'll take a little screen video for you!
Reply
Sam 15 years ago
Kevin Liew Admin 15 years ago
From the reply from the top, apparently i have overlooked the potential problem while implementing it and causing the slider to jump quickly after you click on different browser tab. I will do some investigation based on the comment above, and will try to get back to you as soon as possible.
Reply
denu 15 years ago
What with this note from JQuery Api?:

Because of the nature of requestAnimationFrame(), you should never queue animations using a setInterval or setTimeout loop. In order to preserve CPU resources, browsers that support requestAnimationFrame will not update animations when the window/tab is not displayed. If you continue to queue animations via setInterval or setTimeout while animation is paused, all of the queued animations will begin playing when the window/tab regains focus. To avoid this potential problem, use the callback of your last animation in the loop, or append a function to the elements .queue() to set the timeout to start the next animation.
Reply
Kevin Liew Admin 15 years ago
Hi denu, i have been scratching my head and wondering why the issue. thanks for this info.
Reply
Becky Olson 15 years ago
I need to add images and lots of text to the caption. How do I do that within the alt tag? each slide needs a different image and different layout of the text.
Reply
Kevin Liew Admin 15 years ago
well, you can do it... but you have to make sure all your tags use single quote... noy recommended but it will work.
Reply
Henry 15 years ago
Hey thank u, but i wanna know how to slow down a little the slide, i think is the javascript but i wanna know how an where. Thank u.
Reply
Kevin Liew Admin 15 years ago
it's here: slideShow(2000);
Reply
Boats 15 years ago
thank you for the great scipt, is there a way to put a forward and reverse button on it?
Reply
Kevin Liew Admin 15 years ago
sorry, not in this tutorial.
Reply
JW 15 years ago
can you give me a link that does explain how to add
some nav buttons to the slider? thanks.
is it easy to modify it to get it work with buttons?
Reply
Kevin Liew Admin 15 years ago
It will require fair a bit of effort to make it run. try CSSGlobe EasySlider.
Reply
Sam 15 years ago
I think I have a fix for the speed issue on tabs and loss of focus. Stick this at the bottom of the slideshow() function:

$(window).focus(function () {
timer = setInterval('gallery()', speed);
});
$(window).blur(function () {
clearInterval(timer);
});

it just mimics the functions used for the hover, and pauses the slideshow when the window goes out of focus.

seems to work on chrome, getting mixed results on IE.
Reply
Kevin Liew Admin 15 years ago
that's awesome! thanks for the tips.
Reply
KRLS SLRK 15 years ago
Hi, the tip work in IE but in G. Chrome this not fix the problem... the slideshow-caption increase the speed !! Please, help me. The problem is with the jquery version 1.6.1, with de jquery version 1.4.2 the tip fix in IE and G. Chrome
Reply
Kevin Liew Admin 15 years ago
it something to do with animate(), i still need to find the fix for it:

Note from JQuery Api?:

Because of the nature of requestAnimationFrame(), you should never queue animations using a setInterval or setTimeout loop. In order to preserve CPU resources, browsers that support requestAnimationFrame will not update animations when the window/tab is not displayed. If you continue to queue animations via setInterval or setTimeout while animation is paused, all of the queued animations will begin playing when the window/tab regains focus. To avoid this potential problem, use the callback of your last animation in the loop, or append a function to the elements .queue() to set the timeout to start the next animation.
Because of the nature of requestAnimationFrame(), you should never queue animations using a setInterval or setTimeout loop. In order to preserve CPU resources, browsers that support requestAnimationFrame will not update animations when the window/tab is not displayed. If you continue to queue animations via setInterval or setTimeout while animation is paused, all of the queued animations will begin playing when the window/tab regains focus. To avoid this potential problem, use the callback of your last animation in the loop, or append a function to the elements .queue() to set the timeout to start the next animation.
Reply
aditya 15 years ago
can anyone confirm that Sam's solution works or give a workaround?
or i should pick some other slider?
Please help. I need it urgently
Reply
DJ Nexus 15 years ago
Having the same issue when browsing other tabs, I tried KRLS SLRK's suggestion and reference 1.4.2 and it seems to work fine now.
Reply
Max 15 years ago
Hi, thanks for the great tutorial!!! i have a problem when adding a new image to the slide. i copied one of the <li>'s in the html code and pasted it just below. when previewing the 4th transition loads up fine, its just the captions that stops working after the 1st trasition. what can i do?
Reply
Max 15 years ago
Sorry fixed the mistake i made. I copied this <li class="show"> on all the lists instead of just <li>
Reply
SlyRyder 15 years ago
css tweaks fine, but images not loading, when i replace your images with my images, tried different paths,
in the images folder and not in the images folder, images won't load, everything else great, any suggestions
is it document.ready issue??
Reply
Kevin Liew Admin 15 years ago
anyhow, it should display your images, because it's embed in html. try disable js and see if your image show up. Otherwise, use firebug and inspect your images path.
Reply