This post is Part 5 in The Beginner’s Guide To Writing a jQuery Plugin.
Before software hits your desktop (or your web browser), it typically goes through a number of development cycles. Each cycle is referred to as an iteration and each iteration usually involves developing or modifying some aspect for the project.
In Part 2, we detailed the features and requirements of writing our jQuery plugin. At this point, we’ve laid all of the groundwork for our Slideshow jQuery plugin and ready to get started on the first iteration.
1. Setup The Images
If you’ve been following along with this series, then you should have a copy of the source code and working directory of the project. Note that within the project directory, there is an image directory that contains four images.
These images are the four that we’re going to use while testing our plugin. Let’s go ahead and setup the page to display them.
Open index.html and make the following modifications to the code:
- Update the header tag with something more valuable
- Add a div element that will wrap all of the images
- Include the images in the page
[cc lang=”html”]
jQuery MakeSlideshow Plugin Demo
[/cc]
Once done, your page should look like this within the browser:
2. One Last Change To The Markup
One of the challenges of writing jQuery plugins is striking a balance between ease-of-use and making sure that you don’t interfere with the rest of the elements on a user’s page. After all, the last thing that you want to do is to have someone introduce your plugin only to find that it completely botches their existing presentation.
As such, it’s a good practice to provide a unique name to the elements that are going to be used by your slideshow. Since jQuery has a powerful selector engine and since you access elements on a page using ID’s and classnames, it’s really easy to make sure that your plugin uses only relevant data.
Simply wrap the elements – in this case, images – in a container with a unique class name. Since we already have a div elements wrapping the images, let’s add the class to that element.
[cc lang=”html”]
jQuery MakeSlideshow Plugin Demo
[/cc]
Now, open up the MyjQueryPlugin.js file located in the JavaScript directory and update it so that it looks like this:
[cc lang=”javascript”]
$(function() {
$(‘.my-images’).makeSlideshow();
});
[/cc]
Essentially, you’re saying I want the makeSlideshow plugin to act on all elements with the classname my-images.
3. Stub Out The Slideshow
We’re ready to begin writing code that will actually give life to the slideshow, but before we do that, let’s detail how we want this to work:
- At the start of the slideshow, all images should be hidden except for the first image
- After an arbitrary amount of time – let’s say three seconds – we transition to the next image
- Once we’re at the last image, the slideshow should start over
Sure, we’re used to seeing much fancier effects in a slideshow – and we’ll get to those later in the series – but that’s all that’s required for a basic slideshow, right?
The current state of your slideshow should look like this:
[cc lang=”javascript”]
(function($) {
jQuery.fn.makeSlideshow = function() {
return this.each(function() {
$(this).children(‘:not(:first)’).hide();
};
})(jQuery);
[/cc]
Let’s work through the requirements one-by-one. First, we want to make sure that we hide all images except for the first one. By using jQuery’s children function, not selector, and first selector, we can easily do this:
[cc lang=”javascript”]
(function($) {
jQuery.fn.makeSlideshow = function() {
return this.each(function() {
$(this).children(‘:not(:first)’).hide();
};
})(jQuery);
[/cc]
Reads almost like English, huh? Load it up in your browser and make sure that you see only the first image.
When doing web development, checking your changes after every few lines of code is an excellent habit to adopt.
4. An Unexpected Requirement: The Active Image
Next, we need to make sure that we can advance to the next image after three seconds. JavaScript has a built-in function, setInterval(), that will help us out. setInterval accepts two arguments – a function to fire and an interval (in milliseconds) at which to fire said function.
But wait – there’s a challenge that exists here: when advancing throughout the slideshow, how do we know which image we’re currently displaying? Looping through all of the images to find the one that’s visible is cumbersome and can be exceptionally slow especially with a large set of images.
What if we added a class name to the image that we’re currently displaying and then remove it once its hidden? Let’s try it.
Since the first image is the start of the slideshow, we just need to give it a class name. Let’s call it ‘activeImage.’
[cc lang=”javascript”]
(function($) {
jQuery.fn.makeSlideshow = function() {
return this.each(function() {
$(this).children(‘:not(:first)’).hide();
$(this).children(‘:first’).addClass(‘activeImage’);
};
})(jQuery);
[/cc]
Reresh the page and inspect the image with Firebug. You should see the image has a new class name:
5. Start The Slideshow
Now we should be able to setup the function that will be responsible for proceeding through the slideshow. The general algorithm should go something like this:
- From the active image, find its sibling.
- Hide the currently active image and remove its class name
- Display its sibling and add the ‘activeImage’ class name to it
Our work is cut out for us. By using jQuery’s hide, removeClass, next, show, and addClass functions, we can do this in about one line of code:
[cc lang=”javascript”]
(function($) {
jQuery.fn.makeSlideshow = function() {
return this.each(function() {
$(this).children(‘:not(:first)’).hide();
$(this).children(‘:first’).addClass(‘activeImage’);
setInterval(function() {
$(‘.activeImage’).hide()
.removeClass(‘activeImage’)
.next()
.show()
.addClass(‘activeImage’);
}, 1000);
});
};
})(jQuery);
[/cc]
Load up your browser, and watch it roll. Not bad, huh? Except there’s one problem. What happens when we get to the end of the slideshow?
6. An Unexpected Requirement: Edge Cases
As soon as we get to the last image, we have a bug – the slideshow doesn’t start over. The problem actually exists with a class to the next function that we used above. Since next is looking for the first sibling of the current element and the last image has no sibling, it bombs out.
Here’s how we can go about handling this case:
- Determine if we’re at the last image
- If not, proceed as usual; otherwise, move to the first image rather than the last.
We can check to see if the currently active image has a next sibling by evaluating it’s length property. If it’s great than 0, it exists; otherwise, it doesn’t so we can grab the images first sibling.
[cc lang=”javascript”]
(function($) {
jQuery.fn.makeSlideshow = function() {
return this.each(function() {
$(this).children(‘:not(:first)’).hide();
$(this).children(‘:first’).addClass(‘activeImage’);
setInterval(function() {
if($(‘.activeImage’).next().length > 0) {
$(‘.activeImage’).hide()
.removeClass(‘activeImage’)
.next()
.show()
.addClass(‘activeImage’);
} else {
$(‘.activeImage’).hide()
.removeClass(‘activeImage’)
.siblings(‘:first’)
.show()
.addClass(‘activeImage’);
}
}, 1000);
});
};
})(jQuery);
[/cc]
Refresh your browser and you should be good to go.
7. Refactoring
At this point, we’ve got a working slideshow that fulfills all of the requirements that we’ve outlined. The thing is, we’ve got some duplicate code in both cases of the conditional statement.
Eventually, we’ll want to refactor this so that it’s cleaned up a bit but we’ve covered the first iteration of this project. On top of that, if you’re new to jQuery then we’ve covered a lot of jQuery-specific functionality that’s worth spending sometime reviewing.
Here’s the latest code snapshot of the project. Next up, we’ll introduce a few new options into the slideshow and refactor the code a bit.
[…] jQuery’s Model For Plugin DevelopmentUsing The $ Function When Writing a jQuery PluginDeveloping a Slideshow jQuery Plugin, Iteration OneDeveloping a Slideshow jQuery Plugin, Iteration TwoDeploying Your jQuery PluginThroughout this […]