1/*! 2 * jQuery.slider.js 3 * 4 * Slider plugin to be used on homepages where there's a rotating banner (impact 5 * area). 6 * 7 * This plugin assumes the use of modernizr's 'csstransitions' class. If 8 * modernizr isn't used, a jQuery fallback is in place. 9 * 10 * @author Reinier Kaper <[email protected]> 11 * @example 12$('.slider').slider({ 13 speed: 1000, 14 pause: 5000 15}); 16 */ 17;(function($, window, document, undefined) { 18 /** 19 * Add the slider function to the jQuery functions. 20 * 21 * @param Object options An object containing options for the plugin. 22 * @return Object Returns the jQuery object. 23 */ 24 $.fn.slider = function(options) { 25 /** 26 * The default options for the plugin. 27 */ 28 var defaults = { 29 speed: 1000, // animation speed, if provided 30 pause: 5000, // wait time between slides 31 useCSS: $('html').hasClass('csstransitions'), 32 // A collection of animation objects for browsers that don't support 33 // CSS transitions. 34 // 35 // These objects should idealy reflect the CSS classes and can be 36 // tweaked if needed. 37 animations: { 38 dots: { 39 inactive: { 40 'opacity': 0, 41 'bottom': '-1.5em' 42 }, 43 active: { 44 'opacity': 1, 45 'bottom': '1em' 46 } 47 }, 48 arrows: { 49 next: { 50 inactive: { 51 'right': '-1em', 52 'opacity': 0 53 }, 54 active: { 55 'right': 0, 56 'opacity': 1 57 } 58 }, 59 prev: { 60 inactive: { 61 'left': '-1em', 62 'opacity': 0 63 }, 64 active: { 65 'left': 0, 66 'opacity': 1 67 } 68 } 69 }, 70 slides: { 71 inactive: { 72 'z-index': 1, 73 'opacity': 0 74 }, 75 animating_in: { 76 'z-index': 3, 77 'opacity': 1 78 }, 79 animating_out: { 80 'z-index': 3, 81 'opacity': 1 82 }, 83 active: { 84 'z-index': 2, 85 'opacity': 1 86 } 87 } 88 } 89 }; 90 /** 91 * Extend the options with all the defaults and overwrite any supplied 92 * options. 93 */ 94 options = $.extend(defaults, options); 95 /** 96 * Loop through each item that the plugin is attached to and return the 97 * object for chaining. 98 */ 99 this.each(function() { 100 var $slider, 101 $slides, 102 $controls, 103 $dotsAll, 104 $dots, 105 speed, 106 calls = [], 107 currentIndex, 108 nextIndex, 109 xStart, 110 xEnd, 111 totalSlides, 112 timer = null, 113 isAnimating = false; 114 $slider = $(this); 115 $slides = $slider.find('.slider__slide'); 116 $controls = $slider.find('.slider__controls'); 117 $arrows = $controls.find('.slider__arrow'); 118 $arrowNext = $controls.find('.slider__arrow--next'); 119 $arrowPrev = $controls.find('.slider__arrow--prev'); 120 $dots = $controls.find('.slider__dots'); 121 $dotsAll = $dots.find('.slider__dot'); 122 totalSlides = $slides.length; 123 /** 124 * Initializes the plugin by pre-loading images, hiding slides, and 125 * hiding controls. 126 */
127 function init() { 128 // Give the slider an 'is-loading' class. 129 $slider.addClass('is-loading'); 130 speed = Math.round(options.speed/100)/10; 131 // If the browser supports CSS transitions, set-up the 132 // animations first for each object. 133 if (options.useCSS) { 134 $slides.addClass('is-inactive'); 135 // $([$slides, $arrows, $dots]).each(function() { 136 // this 137 // .css({ 138 // '-webkit-transition-duration': speed + 's', 139 // '-moz-transition-duration': speed + 's', 140 // '-o-transition-duration': speed + 's', 141 // 'transition-duration': speed + 's' 142 // }); 143 // }); 144 } else { 145 $slides.css(options.animations.slides.inactive); 146 } 147 $slides.show(); 148 // Add all the images to an array for preloading and add them 149 // as a background to the slide. 150 151 // Load all the images and once done, show the first slide and 152 // the controls. 153 $.when.apply($, calls).then(function() { 154 // Give the slider an 'is-loaded' class and remove the 155 // 'is-loading' class. 156 $slider 157 .removeClass('is-loading') 158 .addClass('is-loaded'); 159 // Show the first slide. 160 showSlide(0); 161 // SHow the controls if there is more than 1 slide. 162 if (totalSlides > 1) { 163 showControls(); 164 } 165 }); 166 } 167 init(); 168 /** 169 * Shows all the slider controls. 170 */ 171 function showControls() { 172 if (options.useCSS) { 173 $arrows.addClass('is-active'); 174 $dots.addClass('is-active'); 175 } else { 176 $arrowNext 177 .animate(options.animations.arrows.next.active, options.speed); 178 $arrowPrev 179 .animate(options.animations.arrows.prev.active, options.speed); 180 $dots 181 .animate(options.animations.dots.active, options.speed); 182 } 183 } 184 /** 185 * Shows a (specific) slide. If no index is specified it will show 186 * the next slide in the sequence. 187 * 188 * @param {Number} index The index number of the slide to show. 189 */ 190 function showSlide(index) { 191 var $currentSlide, 192 $nextSlide, 193 $currentDot; 194 // Only show a slide if the slider isn't in the process of 195 // animating another slide. 196 if (!isAnimating) { 197 // Remove the current timer to prevent slides from 198 // automatically animating. 199 clearInterval(timer); 200 timer = null; 201 isAnimating = true; 202 nextIndex = index; 203 $currentSlide = $slides.eq(currentIndex); 204 $nextSlide = $slides.eq(nextIndex); 205 // Update the controls. 206 $dotsAll 207 .removeClass('is-active') 208 .eq(nextIndex) 209 .addClass('is-active'); 210 if (options.useCSS) { 211 $currentSlide 212 .addClass('is-animating-out') 213 .removeClass('is-active'); 214 // Animate the next slide. 215 $nextSlide 216 .addClass('is-animating-in') 217 .removeClass('is-inactive'); 218 setTimeout(function() { 219 // Make the previous slide inactive. 220 $currentSlide 221 .removeClass('is-animating-out') 222 .addClass('is-inactive'); 223 // Make the new slide active. 224 $nextSlide 225 .removeClass('is-animating-in') 226 .addClass('is-active'); 227 // Update the global variables. 228 currentIndex = nextIndex; 229 isAnimating = false;
230 // Reset the timer. 231 if (totalSlides > 1) { 232 timer = setInterval(function() { 233 nextSlide(); 234 }, options.pause); 235 } 236 }, options.speed); 237 } else { 238 $currentSlide 239 .animate(options.animations.slides.animating_out); 240 $nextSlide 241 .animate(options.animations.slides.animating_in, options.speed, function() { 242 $currentSlide 243 .css(options.animations.slides.inactive); 244 $nextSlide 245 .css(options.animations.slides.active); 246 // Update the global variables. 247 currentIndex = nextIndex; 248 isAnimating = false; 249 // Reset the timer. 250 if (totalSlides > 1) { 251 timer = setInterval(function() { 252 nextSlide(); 253 }, options.pause); 254 } 255 }); 256 } 257 } 258 } 259 /** 260 * Shows the next slide in the sequence. 261 */ 262 function nextSlide() { 263 var nextIndex; 264 nextIndex = currentIndex < totalSlides ? currentIndex + 1 : 0; 265 nextIndex = nextIndex % totalSlides; 266 showSlide(nextIndex); 267 } 268 /** 269 * Shows the previous slide in the sequence. 270 */ 271 function previousSlide() { 272 var nextIndex; 273 nextIndex = currentIndex > 0 ? currentIndex - 1 : totalSlides - 1; 274 nextIndex = nextIndex % totalSlides; 275 showSlide(nextIndex); 276 } 277 /* ============================================================== 278 Events 279 ============================================================== */ 280 // When the user swipes a slide, go to the next or previous slide, 281 // depending on the direction of the gesture. 282 // 283 // This is currently bugged in Chrome on mobile devices, as events 284 // need to be prevented from their default behavior. 285 $slider.on('touchstart', function(event) { 286 xStart = event.originalEvent.touches[0].pageX; 287 }); 288 $slider.on('touchend', function(event) { 289 xEnd = event.originalEvent.changedTouches[0].pageX; 290 if (xStart - xEnd <= -50 && totalSlides > 1) { 291 previousSlide(); 292 } else if (xStart - xEnd >= 50 && totalSlides > 1) { 293 nextSlide(); 294 } 295 }); 296 // When the user clicks one of the dots, the slider switches to that 297 // associated slide, unless the slider is already animating. 298 $dotsAll 299 .on('click', function() { 300 var $dot, 301 index, 302 currentIndex; 303 $dot = $(this); 304 index = $dot.index(); 305 currentIndex = $slides.index($('.slider__slide.is-active')); 306 if (index !== currentIndex) { 307 showSlide(index); 308 } 309 }); 310 // Previous and Next arrows trigger the prvious or next slide to 311 // animate. 312 $arrows 313 .on('click', function() { 314 var $arrow, 315 isPrev; 316 $arrow = $(this); 317 isPrev = $arrow.hasClass('slider__arrow--prev'); 318 if (isPrev) { 319 previousSlide(); 320 } else { 321 nextSlide(); 322 } 323 }); 324 }); 325 /** 326 * Return the object for chaining. 327 */ 328 return this; 329 }; 330})(jQuery, window, document);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.