I’ve written several versions of this functionality, and each time I revisit it, it gets simpler and I feel silly for how complicated I made it before. The thing to remember when you’re working with jQuery is to always leverage the DOM. Christian Montoya has a good writeup about how he came to the same realization, and it’s worth a read.
In the meantime, here’s my latest iteration of cycling through items in an unordered list. In the example below, I’ve just put straight-up text in the list items, but they could contain entire divs of content if you wanted.
We’ll start by verifying that there’s more than one item before we do all the rest of the work. (Of course, if your list length doesn’t vary, this if isn’t necessary.)
12345
var$list=$('#myList');if($list.length>1){...}
Following the principles of progressive enhancement, we don’t want to include navigation elements in the HTML if they will only work with Javascript; rather, we want to add them with Javascript:
123456789101112
var$list=$('#myList');if($list.length>1){// put the nav before the list$list.before('');// style the nav as needed$('#nav').css({textAlign:'right'});$('#nav img').css({cursor:'pointer'});$('#nav img:first').attr('src','backButton.gif');$('#nav img:last').attr('src','forwardButton.gif');}
The comes the fun part: adding the behaviors to the nav buttons. This is where it pays to keep in mind the power of the DOM; in past iterations of this, I’ve seriously overthought the logic.
var$list=$('#myList');if($list.length>1){// put the nav before the list$list.before('');// style the nav as needed$('#nav').css({textAlign:'right'});$('#nav img').css({cursor:'pointer'});// add the back button behavior$('#nav img:first').attr('src','backButton.gif').click(function(){$('li:visible',$list).hide().prev('li').show();});// add the forward button behavior$('#nav img:last').attr('src','forwardButton.gif').click(function(){$('li:visible',$list).hide().next('li').show();});}
But what happens if there’s not a next li when you click on the forward button, or a previous li when you click on the back button?
12345678910111213141516171819202122
var$list=$('#myList');if($list.length>1){// put the nav before the list$list.before('');// style the nav as needed$('#nav').css({textAlign:'right'});$('#nav img').css({cursor:'pointer'});// add the back button behavior$('#nav img:first').attr('src','backButton.gif').click(function(){$('li:visible',$list).hide().prev('li').show();// if there wasn't a previous li,// show the last li in the listif($('li:visible',$list).length
One last thing: we need to hide all the list items and then show the first one:
1234567891011121314151617181920212223242526
var$list=$('#myList');if($list.length>1){// hide all the list items and show the first one$('li',$list).hide().eq(0).show();// put the nav before the list$list.before('');// style the nav as needed$('#nav').css({textAlign:'right'});$('#nav img').css({cursor:'pointer'});// add the back button behavior$('#nav img:first').attr('src','backButton.gif').click(function(){$('li:visible',$list).hide().prev('li').show();// if there wasn't a previous li,// show the last li in the listif($('li:visible',$list).length
For extra fun:
Randomly reorder the list items before you add the rest of the code
Instead of show() and hide(), try fadeIn() and fadeOut()