Introduction and HTML/CSS Setup
Alright, today we're going to be building a basic jQuery slider, an image slider. Now, there's a lot of great jQuery plugins out there for this—FlexSlider, Royal Slider, all sorts of good ones. They have more features than we're going to be able to build in a couple minutes, but we're learning jQuery so this is a great example. Let's get into it.
I have a slider here. Let me show you the HTML behind it. I have a wrapper div with the ID of slider, and then I have a UL with class slides, and then I have a bunch of LIs that have a class of slide. Each one of these has just an image that I've put in there: slider 1, 2, 3, 4, 5. And then I finished it with my first one as well. They're going to be sliding to the left and I want the first one to be able to slide onto the screen at the very end. We'll see what that means in a minute.
So here's the CSS driving it. The slider wrapper has a width of 720 and any overflow is hidden. And then all the slides are going left to right all the way out, so the slides UL has a width of 6,000 pixels. And then all the slides float left. So basically what you're seeing here is, I can show you, is if I were to make the margin left 100 pixels... there you go. So as the UL, the slides UL, slides to the left with a negative margin, it's going to move there until we run out of slides. And so basically all our JavaScript needs to do is move this UL back and forth. That's the basics. Oh yeah, and then when it gets to the end here, let me go back up here. When it gets to the end, we need to somehow know that we are on the last slide and then boom, go to margin zero. And the user won't even notice it because it's the exact same slide. So we need to go back to margin zero when we hit the last slide.
Core JavaScript Concepts: setInterval and .animate()
So let's get into the code. One piece of code you'll need to know in JavaScript, if you don't know how to do it yet, is setInterval. setInterval takes two things: it takes a function and then it takes a time frame, like let's say a 1000 milliseconds, which is one second. And every 1000 milliseconds it will fire this function. So as an example, I can do this. I can go every 1000 milliseconds, we're going to log the date, new Date(). There you go. And so you'll notice here in the console it's going to log the new date, going up one second every time.
Another thing you can do with setInterval is you can save its value. myInterval = setInterval... so now if I save that, it's going to start over again. And now I can go clearInterval(myInterval), give it the one you want to clear, and it stops it. So that's kind of... we don't want it to automatically run forever, we want to have the ability to start it and stop it. So we're going to save our interval.
And then we need to use jQuery to animate this slider. And how you do that is you do, I'll show you over here, you do jQuery selector, .animate(), and then you're going to give it an object, which is all the CSS properties and what you want to animate them to. You can animate more than one thing at a time, but in our case we're just doing margin-left. A time frame again, like how many milliseconds, and then a callback, which is if you want it to do something after the animation is complete, the callback function will be there. So we can just go $('#slider .slides').animate({ 'margin-left': '-=720' }, 1000); to let's make it 720. And then I'll give it, let's do that over the course of one second. There you go. So now it just went to my second slide. I can also do negative. If I make it a string, I can go negative equals 720 and it's not going to go to 720, it's going to keep minusing 720 every time I run that. So that's going to keep minusing 720, keep minusing 720. Or I can just actually go to minus 720, which is slide number two, if that made sense.
Initial Slider Implementation
So let's go ahead and build out this thing here. We're going to start by wrapping it in a jQuery document ready function, which is what we always do. And I also always like to start off with comments to set the stage for what I'm going to be building. setInterval is what I'm going to build here. And in that interval, I'm going to animate margin left. And then I'm also going to, if it's the last slide, go to position one, which is zero pixels. And then I also want to add another feature. I want to listen for mouse enter and pause. So if you hover over the slider, I want it to pause, and you know, while I'm looking at that slide. And then resume on mouse leave. So when I leave, I want it to start sliding again. So that's basically what my slider is going to be. Let's start building this out.
setInterval and let's make it run every 3 seconds. And every 3 seconds I'm going to go $slider .slides.animate, just what I showed you before, margin-left is going to go negative equals 720 pixels. Because I don't just want to go to negative 720 pixels, I want to keep subtracting 720 every time. And let's slide for about one second when we do that. There we go. Let's actually save, refresh, and now we should be sliding every 3 seconds. Yeah, over the course of a second. Feels good, feels good. But this is just going to keep going forever. Once we get to slide seven, it doesn't know you're there. It just keeps sliding. So now we need to get a little bit smarter. If it's the last slide, go to position one.
One thing I'm going to do here is I'm going to start... I don't like that all these configuration options are kind of scattered throughout the code. That's kind of a bad idea. So I'm going to start moving things up here. I'm going to go width = 720, which is the width of our slides, which is set in the CSS. It's 720, the slides are all 720. I'm going to go there. animationSpeed = 1000. And then var pause = 3000. So now I'm going to make this pause. There we go. animationSpeed. And I will just go negative equals width. -=' + width. So that basically is the same as saying negative equals 720, except for now I'm just storing my 720 here. So if at any point in time I want to change the configuration, it's all in one place. You'll notice the colors are starting to look a little different now. All my yellows are up here, and there's not very many yellow down here. That's a good sign. That means all my configuration, all the things of the same type tend to be in the same place. Not all code ends up looking this way, but this is definitely a good sign.
Another thing I want to do too, save configuration, is I want to do what's called caching the DOM. I think I've covered this in some other videos, but I don't want to have to look for $slider .slides every time. I want to be able to look for it once and then just reference it every time. So I'm actually going to go var $slider, there we go. So I searched the DOM and I found my slider. I'm using the dollar sign here so I know it's a jQuery object. You can call it just slider, but I want to know that that's not a string or something. I want to remember that that's a jQuery search. So there we go. Slider equals that. And now I can reference it later on. So now every single time the interval fires, I don't have to look for my slider. Except for I'm not actually animating the slider, I'm animating the slide container. So let's get that. slideContainer equals... and what I'm going to do is I'm going to go $slider.find('.slides'). So I've already searched all my web page document and I found this guy and I've kept a track of it, and now I just want to find a guy inside of it. So I'm going to find slides inside. That's a very fast operation. So now once again, you're noticing I've only done my jQuery selector once. So this is going to be a very fast and high performance piece of code. And then I want to go, let's go slides as well, equals $slideContainer.find('.slide'). So that's going to be the whole list of my slide elements. So this is actually slideContainer. Did I not spell that right? Nope, I didn't. Container. There you go. I'm just going to copy-paste that. It's annoying to type that while I'm talking. Okay, so there we go. So just again, to cover what I did here is I only searched my whole HTML web page once right there. And from there on, I'm looking inside that piece that I found to find some specific things I will reference later. So now every time it has to do the animation, it just goes boom, I already know where that is. I'm going to find it and animate it. It's a much faster piece of code.
Implementing the Infinite Loop
So now what I need to do is I need to start checking afterwards to see if I'm on my current, if I'm on the last slide or not. What I will do here is I'm going to add a callback. Remember I said the third thing you can pass to animate is a callback. So once the animation is done, I want to check if I'm on the last slide. If I am on the last slide, I go to the first slide. So, if... and I'm going to do this, I'm going to, let's do this. Let's go ++currentSlide. Wait, I didn't save current slide here. currentSlide = 1. I always want to start on slide one. So I'm going to go currentSlide++. So I'm boosting that up. So the first time it's going to turn it to two, then three, then four. Every time I plus plus that, it's just going to go up one number.
If currentSlide equals $slides.length, so if currentSlide is, if we're on the last one, currentSlide will be 1, 2, 3, 4, 5, 6. And then if that is the same as my length, which is the count. So if I can show you that there's slide. If I do $slides.length then it's going to be six. There are six slide elements on my page. So if currentSlide is the same as $slides.length, then we want to make currentSlide = 1. We want to make sure that goes back to one. And then we're going to go $slideContainer, just .css(). We're not going to animate this time. We want it to happen immediately and we want it to happen behind the scenes. We want to make the margin-left zero. Okay?
So every time we animate, we bump up our number of our current slide. If it now equals our slide's length, then we're going to go back to number one. That should work. Let's check it out. And I'm going to set our pause to one second so this should happen faster. Uh oh, slideConainer is not defined. Right, because I can't spell. Here we go. slideContainer. $slideContainer is still not found. What the heck? Cannot type. Yep, there we go. All right, so here we go. We're sliding through every one second and then we should know here... nice. Okay, so once we got to the last one, we realized that we were on the last one and we set this back to one and then we went to margin-left: 0. Great. And that's going to get really annoying for it to move that fast. So now all we have to do is add this. We've taken these three out, check, check, check.
Adding Pause and Resume on Hover
Let's just do that mouse enter and that pause part and we're done with our slider. This is actually going to be a little trickier than we think. So let's go here. $slideContainer, actually we're just going to do $slider. $slider.on('mouseenter', ...) we're going to pause slider. And then .on('mouseleave', ...) we're going to resume slider, or start slider. Okay.
Now the thing is, is we actually don't have a way of pausing our slider right now. So what we need to do is let's actually make an interval. This will be our thing that we start and stop. And let's make a function for startSlider and a function for stopSlider. So now I'm going to put this setInterval within my startSlider function. interval = setInterval... Okay. So now, whenever I click startSlider, it's going to store my interval in this guy. I had to define this outside of my function, because if I did var interval in here instead, I can't access that interval anywhere outside of the function. It's kind of within what's called the scope. interval only exists within this function, so now I can't talk to it from outside. So what I had to do is I had to define interval here, and now I can... interval is talking to that guy. So I can startSlider, and then function stopSlider is easy. stopSlider is just going to clear the interval. And that's why I had to define interval outside of my function, because I have to be able to clear it. And I can show you in a little bit why that wouldn't work the other way.
So now we go, I have my... Oh, I called it pauseSlider, didn't I? Well we're going to call this pauseSlider then. I'll just call it stop. So now when I mouse enter over slider, it's going to stop it. And I mouse leave it's going to start it. And guess what? When I hit, when I stop it and it refreshes, when I save it and refreshes, nothing happens because startSlider is never being called. So I need to at the very end of all things, just start my slider. Now it should work. Great. So it's sliding. Excellent. Now if I hover, it should stop sliding. Of course, I'll probably need to click on this. Okay, if I hover... there you go, it stopped. And now if I mouse leave... Of course, I just called it mouseleave. Okay, let's try this again. It's paused. Let's pause it, make sure it's paused. It is paused. Let's hover and it should start up again. Excellent.
Explaining Variable Scope and Conclusion
So let's just one once again cover what we did to make sure it's not super confusing. And I'm going to just, I don't know what I'm going to do with you, I'm going to just comment you out so that thing doesn't slide all day. Alright.
So we made a function startSlider and stopSlider, so that way we could say on mouse enter, we're going to stopSlider, on mouse leave we're going to startSlider. And then we defined this interval thing here. Let me go... just for your learning about JavaScript, if we did interval here, we just made interval a new variable, but it's only going to stay within my function. So stopSlider will not work because when I hit clearInterval, it's not going to know where to find interval. A function only has access to the variables inside of it and the variables up one level, which are all these guys. It's not going to have, it's not going to have access to variables defined inside of another function. Here, let me show you this in operation right here. So I'm going to save and I'm going to hover... interval is not defined it says. Because it doesn't know what to do. So when I try to stop the slider, it can't find interval. And so there's your problem. So we're just going to go var interval, we're just going to define it and not give it any kind of value whatsoever. And now everybody else can talk to it. We can put values into it and we can mess with the values that are there.
So there you go, that's how to build a jQuery slider. Hope it made sense. Feel free to watch it again. Drop me some comments if there are things that don't make sense. Have yourself a great day.