Tuesday 11 March 2014

jQuery: Simple slideshow side by side

Simple JQuery Slideshow

In this tutorial we're going to use jQuery to make a slideshow

Part 1 | Part 2 | Part 3
Today I'm going to take you through a simple jQuery slideshow and by going through the process step by step, hopefully show you just how easy it is to come up with an idea and achieve it with jQuery.

A little bit about jQuery

JQuery is JavaScript library that lets you link JavaScript to your HTML. Basically it lets you do things that you might have once done with Flash, but without the associated SEO implications. You can learn more at thejQuery site.

Our Slideshow

Lets imagine that we want a simple slideshow that cycles through slides at a time interval that we can set. We also want forward and back buttons so we can jump around between slides and each slide has a title, a description and a link associated with it.
View the finished slideshow

How our slideshow will work

The most important thing to grasp when using jQuery is that most of the work is done by our CSS. JQuery allows you to add and remove style elements and animate between the changes. This is the basis for making a simple slideshow with jQuery. And since you're already a CSS master, this is going to be really easy!
Basically, our slideshow is just a bunch of images, lined up side by side with the float attribute and viewed through a 'window', which is just a div with it's overflow set to hidden. All the jQuery does is move the slides back and forth by adjusting the left margin on a div that contains all the slides.
Lets start making our slide show. As always when doing something new, break the problem down into steps. The first thing I'm going to do is set up my html and css and then use jQuery to get the images moving. Later on I'll worry about adding text and links and then after that I'll add some buttons so we can navigate forwards and backwards through the slides.
Let's start with the HTML.
<div id="slideshow"> <div id="slideshowWindow"> <div class="slide"> <img src="slide1.jpg" /> </div><!--/slide--> <div class="slide"> <img src="slide2.jpg" /> </div><!--/slide--> <div class="slide"> <img src="slide3.jpg" /> </div><!--/slide--> </div><!--/slideshowWindow--> </div><!--/slideshow-->
You could do this with an unordered list no problem, but because I don't know what we're going to add later, I think it might be prudent to use divs, so I do.
Lets add some css:
#slideshow #slideshowWindow { width:500px; height:257px; margin:0; padding:0; position:relative; overflow:hidden; } #slideshow #slideshowWindow .slide { margin:0; padding:0; width:500px; height:257px; float:left; position:relative; }
I haven't included any styling here for the outer #slideshow div but you can add whatever you need to position the slideshow on your page. The slideshowWindow div is essentially the 'window' through which we will view our slideshow. The important thing to notice here is that the overflow is set to hidden. And of course the slide div holds a single slide and later on whatever content will be associated with it like the title, description and link.
Now we need to add some jQuery to make our slides move. If you haven't got it already, you need to download jQuery. Once you've got it, you'll need to include the file in the head section of your page, making sure that you've got the path correct:
<script type="text/javascript" src="jquery.js"></script>
Now we can start writing the jQuery code that'll make out slides move.
The first thing we need is our document.ready function. In the head, below where you called the jQuery file, add the following:
<script type="text/javascript"> $(document).ready(function() { //our code will go here }); </script>
Now we're set up and ready to go. First we're going to need some variables. Type the following in the document.ready function:
var currentPosition = 0; var slideWidth = 500; var slides = $('.slide'); var numberOfSlides = slides.length;
The first variable records which slide we're currently viewing. The slideWidth variable is self explanatory. Next we have a variable called slides which lets us refer to our slides in the jQuery code and the last variable gives us the number of slides in our slideshow. As you can see, it automatically calculates the number of slides by counting the number of divs that are of the class slide.
To get the slides to line up across the page, we need to add another div. We're going to do this with jQuery. This div will hold all the slides and allow the float:left property to work. Add the following code:
slides.wrapAll('<div id="slidesHolder"></div>')
Now we need to float the slides so they line up side by side.
slides.css({ 'float' : 'left' });
If you remove the overflow:hidden from the slideshowWindow div and run the code now, you'll see what this achieves.
Next we want to set the width of #slidesHolder div. This needs to be set to the width of all the slides added together. We can do this easily in jQuery:
$('#slidesHolder').css('width', slideWidth * numberOfSlides);
We're just using jQuery to change the width set in our css. So now we need to move the slides from one to the other. We will require two functions. The first function will determine how far along we are along our sequence of slides, so we know where to go next and so that when we reach the last slide, we know to jump back to the beginning. Here is the function:
function changePosition() { if(currentPosition == numberOfSlides) { currentPosition = 1; } else { currentPosition++; } moveSlide(); }
The first part of the if/else statement deals with when reach the end of the slide show. When we come to the last slide we want to jump back to the beginning, otherwise the currentSlide variable is simply incremented by 1 and then another function moveSlide is called.
function moveSlide() { $('#slideHolder').animate({'marginLeft' : slideWidth*(-currentPosition)}); }
This is the business end of the jQuery code, this function sets the left margin of the slidesHolder div to the width of the slide multiplied by the slide number and then animates to that from the current left margin. But if you run your code now you'll notice that nothing is happening. That's because we haven't called the changePosition function yet.
We want the slide to change every few seconds so we'll set a timer that calls the function periodically.
First we need to set a variable to hold the timer. Below the other variables, add the following:
var slideShowInterval; var speed = 6000;
As you can see we've also added a variable to control the speed. This is the speed in milliseconds, so 6000 is equal to 6 seconds.
So now we need to set up our timer:
slideShowInterval = setInterval(changePosition, speed);
We're using the jQuery setInterval function. It takes two parameters, the function that it calls and the speed. So this will call the changePosition function (which in turn calls the moveSlide function) every 6 seconds.
Your jQuery code should look like this:
<script type="text/javascript"> $(document).ready(function() { var currentPosition = 0; var slideWidth = 500; var slides = $('.slide'); var numberOfSlides = slides.length; var slideShowInterval; var speed = 3000; slideShowInterval = setInterval(changePosition, speed); slides.wrapAll('<div id="slidesHolder"></div>') slides.css({ 'float' : 'left' }); $('#slidesHolder').css('width', slideWidth * numberOfSlides); function changePosition() { if(currentPosition == numberOfSlides - 1) { currentPosition = 0; } else { currentPosition++; } moveSlide(); } function moveSlide() { $('#slidesHolder') .animate({'marginLeft' : slideWidth*(-currentPosition)}); } }); </script>
Run the script and see what happens. You should have a working slideshow:

Just out of interest, remove the overflow:hidden from the slideshowWindow style. This will give you a good indication of what is really happening.
In the next step we're going to add titles, text and links to the slideshow.

Simple JQuery Slideshow Part 2

In this part we'll add titles, text and links to our slideshow

Part 1 | Part 2 | Part 3
This part is easy. There are a lot of things you could do here, fading in and out and such but I'm just going to keep it simple. Because we used divs instead of an unordered list, this is very easy. Simply add whatever you need into your html and then style in the css to give the desired results.
<div id="slideshow"> <div id="slideshowWindow"> <div class="slide"> <img src="slide1.jpg" /> <div class="slideText"> <h2 class="slideTitle">Slide 1</h2> <p class="slideDes">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p> <p class="slideLink"><a href="#">click here</a></p> </div><!--/slideText--> </div><!--/slide--> <div class="slide"> <img src="slide2.jpg" /> <div class="slideText"> <h2 class="slideTitle">Slide 2</h2> <p class="slideDes">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p> <p class="slideLink"><a href="#">click here</a></p> </div><!--/slideText--> </div><!--/slide--> <div class="slide"> <img src="slide3.jpg" /> <div class="slideText"> <h2 class="slideTitle">Slide 3</h2> <p class="slideDes">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p> <p class="slideLink"><a href="#">click here</a></p> </div><!--/slideText--> </div><!--/slide--> </div><!--/slideshowWindow--> </div><!--/slideshow-->
And the css:
#slideshow #slideshowWindow { width:500px; height:257px; margin:0; padding:0; position:relative; overflow:hidden; } #slideshow #slideshowWindow .slide { margin:0; padding:0; width:500px; height:257px; position:relative; } #slideshow #slideshowWindow .slide .slideText { position:absolute; top:130px; left:0px; width:100%; height:130px; background-image:url(greyBg.png); background-repeat:repeat; margin:0; padding:0; color:#ffffff; font-family:Myriad Pro, Arial, Helvetica, sans-serif; } #slideshow #slideshowWindow .slide .slideText a:link, #slideshow #slideshowWindow .slide .slideText a:visited { color:#ffffff; text-decoration:none; } #slideshow #slideshowWindow .slide .slideText h2, #slideshow #slideshowWindow .slide .slideText p { margin:10px 0 0 10px; padding:0; }
This should give you something like this:

Slide 1

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Slide 2

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Slide 3

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

In the final part of this tutorial we're going to add some navigation so we can move forwards and backwards through the slides.

Simple JQuery Slideshow Part 3

In this part we'll add navigation to our slideshow.

Part 1 | Part 2 | Part 3
Our navigation will consist of two buttons so we can go forward and backward through the slides. We have to be careful that this doesn't mess up our timer.
The first thing we have to do (after we've made our button graphics) is add them to our slideshow. We'll do this with jQuery because if the user doesn't have JavaScript available on their browser, the buttons won't do anything so we don't want the user to see them if that is the case. This way they'll only display if JQuery is available.
Add the buttons to the DOM so they're ready for use straight away on load. Add the following code just under where we set the width for the #slideInner div:
$('#slideshow') .prepend('<span class="nav" id="leftNav">Move Left</span>') .append('<span class="nav" id="rightNav">Move Right</span>');
This code puts in a couple of span tags which then get replaced by our button images:
.nav { display:block; text-indent:-10000px; position:absolute; cursor:pointer; } #leftNav { top:223px; left:780px; width:94px; height:34px; background-image:url(previous.png); background-repeat:no-repeat; z-index:999; } #rightNav { top:225px; left:910px; width:53px; height:26px; background-image:url(next.png); background-repeat:no-repeat; z-index:999; }
If you run the slideshow now you still won't see them because we haven't told our code to display them. We'll write a function to do that now. Note that if we're on the first slide, we don't want the back button to display, likewise if we're on the last slide, we don't want to see the forward button.
function manageNav(position) { //hide left arrow if position is first slide if(position==0){ $('#leftNav').hide() } else { $('#leftNav').show() } //hide right arrow is slide position is last slide if(position==numberOfSlides-1){ $('#rightNav').hide() } else { $('#rightNav').show() } }
If you run the slideshow now you still won't see the buttons because we haven't called the function. Below where you added the buttons to the DOM, add the following:
manageNav(currentPosition);
We also have to alter our changePosition function to call the manageNav function every time the slide changes:
function changePosition() { if(currentPosition == numberOfSlides - 1) { currentPosition = 0; manageNav(currentPosition); } else { currentPosition++; manageNav(currentPosition); } moveSlide(); }
Now our slideshow has forward and back buttons that display at the correct time but they still don't do anything if you click them. We have to tell them what to do when clicked:
$('.nav').bind('click', function() { //determine new position currentPosition = ($(this).attr('id')=='rightNav') ? currentPosition+1 : currentPosition-1; //hide/show controls manageNav(currentPosition); clearInterval(slideShowInterval); slideShowInterval = setInterval(changePosition, speed); moveSlide(); });
This code is a little bit complicated but basically when a button is clicked it works out which one and then either adds or subtracts 1 from the currentPosition variable. The moveSlide function is then called, which uses the new currentPosition variable. You'll notice that the timer is reset when a button is clicked.
The complete jQuery code should look like this:
$(document).ready(function() { var currentPosition = 0; var slideWidth = 500; var slides = $('.slide'); var numberOfSlides = slides.length; var slideShowInterval; var speed = 3000; //Assign a timer, so it will run periodically slideShowInterval = setInterval(changePosition, speed); slides.wrapAll('<div id="slidesHolder"></div>') slides.css({ 'float' : 'left' }); //set #slidesHolder width equal to the total width of all the slides $('#slidesHolder').css('width', slideWidth * numberOfSlides); $('#slideshow') .prepend('<span class="nav" id="leftNav">Move Left</span>') .append('<span class="nav" id="rightNav">Move Right</span>'); manageNav(currentPosition); //tell the buttons what to do when clicked $('.nav').bind('click', function() { //determine new position currentPosition = ($(this).attr('id')=='rightNav') ? currentPosition+1 : currentPosition-1; //hide/show controls manageNav(currentPosition); clearInterval(slideShowInterval); slideShowInterval = setInterval(changePosition, speed); moveSlide(); }); function manageNav(position) { //hide left arrow if position is first slide if(position==0){ $('#leftNav').hide() } else { $('#leftNav').show() } //hide right arrow is slide position is last slide if(position==numberOfSlides-1){ $('#rightNav').hide() } else { $('#rightNav').show() } } /*changePosition: this is called when the slide is moved by the timer and NOT when the next or previous buttons are clicked*/ function changePosition() { if(currentPosition == numberOfSlides - 1) { currentPosition = 0; manageNav(currentPosition); } else { currentPosition++; manageNav(currentPosition); } moveSlide(); } //moveSlide: this function moves the slide function moveSlide() { $('#slidesHolder') .animate({'marginLeft' : slideWidth*(-currentPosition)}); } });
If you run the slideshow now you should have the finished article:
Move Left

Slide 1

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Slide 2

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Slide 3

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

I hope you found this useful. As you have seen, the trick with jQuery is to remember that it's all in the css.

No comments:

Post a Comment