In this post I'm going to show you how to add some animations to a jQuery content slider when each slide comes into sight. To accomplish this, we'll create a very simple jQuery plugin that not only handles a content slider but also add some animations to the slides. As always, we start with our underlying HTML structure, which is as follows:
<div id="slider"> <div id="slider-wrapper"> <div class="slide"> <h2>...</h2> <div class="animated">...</div> </div> <!--more slides--> </div> </div> <div id="controls"> <a href="#" id="previous">...</a> <a href="#" id="next">...</a> </div>
As you may have already guessed, the element with class animated
is the element inside each slide that is going to be animated. Now let's take a look at the structure of our plugin:
(function($) { $.fn.contentSlider = function(options) { // 1. Settings and private members // 2. Sliding and animations }; })(jQuery);
First our settings and private members:
var that = this; options = $.extend({ previous: $('#previous'), next: $('#next'), animated: $('div.animated', that), slide: $('div.slide', that), speed: 'slow', wrapper: $('#slider-wrapper', that) }, options); var getSlidePositions = function() { var positions = []; options.slide.each(function(index) { var $slide = $(this); var left = $slide.position().left; positions[index] = left; }); return positions; }; var slideIndex = 0; var size = options.slide.length;
Let's see these components in details:
that
is an internal reference to the jQuery object elementoptions
are our default plugin optionsgetSlidePositions()
returns an array containing all the left offsets of our slidesslideIndex
is the current slide index to be used both for selecting a slide offset within the array returned by the previous function and for selecting a slide using theeq()
methodsize
is the number of slides contained in our slider.
We simply have to move our slider container leftwards or rightwards depending on the current position selected in our position array. Then, using the same index, we select the current slide and animate our target element:
return that.each(function() { var pos = getSlidePositions(); options.previous.click(function(event) { if(slideIndex > 0) { slideIndex--; } else { slideIndex = size; slideIndex--; } options.slide.eq(slideIndex). find('div.animated').hide(); options.wrapper.animate({ left: - pos[slideIndex] }, options.speed, function() { options.slide.eq(slideIndex). find('div.animated'). fadeIn(options.speed); }); event.preventDefault(); }); options.next.click(function(event) { slideIndex++; if(slideIndex == size) { slideIndex = 0; } options.slide.eq(slideIndex). find('div.animated').hide(); options.wrapper.animate({ left: - pos[slideIndex] }, options.speed, function() { options.slide.eq(slideIndex). find('div.animated'). fadeIn(options.speed); }); event.preventDefault(); }); });
Before animating our target element we need to make sure that it's already hidden or, in other words, that the animation state has been reset to its default state. That's why we use hide()
before invoking the animate()
method and its callback function. By using the callback function of this method we actually animate our element only when the slide is in sight. You can see the demo below.