1/* 2 * jQuery FlexSlider v1.7 3 * http://flex.madebymufffin.com 4 * 5 * Copyright 2011, Tyler Smith 6 * Free to use under the MIT license. 7 * http://www.opensource.org/licenses/mit-license.php 8 * 9 * Shoutout to Darin Richardson for his wonderful contributions to the betterment of FlexSlider 10 */ 11 12;(function ($) { 13 14 //FlexSlider: Object Instance 15 $.flexslider = function(el, options) { 16 var slider = el; 17 18 slider.init = function() { 19 slider.vars = $.extend({}, $.flexslider.defaults, options); 20 slider.data('flexslider', true); 21 slider.container = $('.slides', slider); 22 slider.slides = $('.slides > li', slider); 23 slider.count = slider.slides.length; 24 slider.animating = false; 25 slider.currentSlide = slider.vars.slideToStart; 26 slider.animatingTo = slider.currentSlide; 27 slider.atEnd = (slider.currentSlide == 0) ? true : false; 28 slider.eventType = ('ontouchstart' in document.documentElement) ? 'touchstart' : 'click'; 29 slider.cloneCount = 0; 30 slider.cloneOffset = 0; 31 32 //Test for controlsContainer 33 if (slider.vars.controlsContainer != "") { 34 slider.controlsContainer = $(slider.vars.controlsContainer).eq($('.slides').index(slider.container)); 35 slider.containerExists = slider.controlsContainer.length > 0; 36 } 37 //Test for manualControls 38 if (slider.vars.manualControls != "") { 39 slider.manualControls = $(slider.vars.manualControls, ((slider.containerExists) ? slider.controlsContainer : slider)); 40 slider.manualExists = slider.manualControls.length > 0; 41 } 42 43 /////////////////////////////////////////////////////////////////// 44 // FlexSlider: Randomize Slides 45 if (slider.vars.randomize) { 46 slider.slides.sort(function() { return (Math.round(Math.random())-0.5); }); 47 slider.container.empty().append(slider.slides); 48 } 49 /////////////////////////////////////////////////////////////////// 50 51 /////////////////////////////////////////////////////////////////// 52 // FlexSlider: Slider Animation Initialize 53 if (slider.vars.animation.toLowerCase() == "slide") { 54 slider.css({"overflow": "hidden"}); 55 if (slider.vars.animationLoop) { 56 slider.cloneCount = 2; 57 slider.cloneOffset = 1; 58 slider.container.append(slider.slides.filter(':first').clone().addClass('clone')).prepend(slider.slides.filter(':last').clone().addClass('clone')); 59 } 60 slider.container.width(((slider.count + slider.cloneCount) * slider.width()) + 2000); //extra width to account for quirks 61 //create newSlides to capture possible clones 62 slider.newSlides = $('.slides > li', slider); 63 //Timeout function to give browser enough time to get proper width initially 64 setTimeout(function() { 65 slider.newSlides.width(slider.width()).css({"float": "left"}).show(); 66 }, 100); 67 slider.container.css({"marginLeft": (-1 * (slider.currentSlide + slider.cloneOffset))* slider.width() + "px"}); 68 } else { //Default to fade 69 slider.slides.css({"width": "100%", "float": "left", "marginRight": "-100%"}).eq(slider.currentSlide).fadeIn(400); 70 } 71 /////////////////////////////////////////////////////////////////// 72 73 /////////////////////////////////////////////////////////////////// 74 // FlexSlider: Control Nav 75 if (slider.vars.controlNav) { 76 if (slider.manualExists) { 77 slider.controlNav = slider.manualControls; 78 } else { 79 var controlNavScaffold = $('<ol class="flex-control-nav"></ol>'); 80 var j = 1; 81 for (var i = 0; i < slider.count; i++) { 82 controlNavScaffold.append('<li><a>' + j + '</a></li>'); 83 j++; 84 } 85 86 if (slider.containerExists) { 87 $(slider.controlsContainer).append(controlNavScaffold); 88 slider.controlNav = $('.flex-control-nav li a', slider.controlsContainer); 89 } else { 90 slider.append(controlNavScaffold); 91 slider.controlNav = $('.flex-control-nav li a', slider); 92 } 93 } 94 95 slider.controlNav.eq(slider.currentSlide).addClass('active'); 96 97 slider.controlNav.bind(slider.eventType, function(event) { 98 event.preventDefault(); 99 if (!$(this).hasClass('active')) { 100 slider.flexAnimate(slider.controlNav.index($(this)), slider.vars.pauseOnAction); 101 } 102 }); 103 }
104 /////////////////////////////////////////////////////////////////// 105 106 ////////////////////////////////////////////////////////////////// 107 //FlexSlider: Direction Nav 108 if (slider.vars.directionNav) { 109 var directionNavScaffold = $('<ul class="flex-direction-nav"><li><a class="prev" href="#">' + slider.vars.prevText + '</a></li><li><a class="next" href="#">' + slider.vars.nextText + '</a></li></ul>'); 110 111 if (slider.containerExists) { 112 $(slider.controlsContainer).append(directionNavScaffold); 113 slider.directionNav = $('.flex-direction-nav li a', slider.controlsContainer); 114 } else { 115 slider.append(directionNavScaffold); 116 slider.directionNav = $('.flex-direction-nav li a', slider); 117 } 118 119 //Set initial disable styles if necessary 120 if (!slider.vars.animationLoop) { 121 if (slider.currentSlide == 0) { 122 slider.directionNav.filter('.prev').addClass('disabled'); 123 } else if (slider.currentSlide == slider.count - 1) { 124 slider.directionNav.filter('.next').addClass('disabled'); 125 } 126 } 127 128 slider.directionNav.bind(slider.eventType, function(event) { 129 event.preventDefault(); 130 var target = ($(this).hasClass('next')) ? slider.getTarget('next') : slider.getTarget('prev'); 131 132 if (slider.canAdvance(target)) { 133 slider.flexAnimate(target, slider.vars.pauseOnAction); 134 } 135 }); 136 } 137 ////////////////////////////////////////////////////////////////// 138 139 ////////////////////////////////////////////////////////////////// 140 //FlexSlider: Keyboard Nav 141 if (slider.vars.keyboardNav && $('ul.slides').length == 1) { 142 $(document).keyup(function(event) { 143 if (slider.animating) { 144 return; 145 } else if (event.keyCode != 39 && event.keyCode != 37){ 146 return; 147 } else { 148 if (event.keyCode == 39) { 149 var target = slider.getTarget('next'); 150 } else if (event.keyCode == 37){ 151 var target = slider.getTarget('prev'); 152 } 153 154 if (slider.canAdvance(target)) { 155 slider.flexAnimate(target, slider.vars.pauseOnAction); 156 } 157 } 158 }); 159 } 160 ////////////////////////////////////////////////////////////////// 161 162 ////////////////////////////////////////////////////////////////// 163 //FlexSlider: Slideshow Setup 164 if (slider.vars.slideshow) { 165 //pauseOnHover 166 if (slider.vars.pauseOnHover && slider.vars.slideshow) { 167 slider.hover(function() { 168 slider.pause(); 169 }, function() { 170 slider.resume(); 171 }); 172 } 173 174 //Initialize animation 175 slider.animatedSlides = setInterval(slider.animateSlides, slider.vars.slideshowSpeed); 176 } 177 ////////////////////////////////////////////////////////////////// 178 179 ////////////////////////////////////////////////////////////////// 180 //FlexSlider: Pause/Play 181 if (slider.vars.pausePlay) { 182 var pausePlayScaffold = $('<div class="flex-pauseplay"><span></span></div>'); 183 184 if (slider.containerExists) { 185 slider.controlsContainer.append(pausePlayScaffold); 186 slider.pausePlay = $('.flex-pauseplay span', slider.controlsContainer); 187 } else { 188 slider.append(pausePlayScaffold); 189 slider.pausePlay = $('.flex-pauseplay span', slider); 190 } 191 192 var pausePlayState = (slider.vars.slideshow) ? 'pause' : 'play'; 193 slider.pausePlay.addClass(pausePlayState).text((pausePlayState == 'pause') ? slider.vars.pauseText : slider.vars.playText); 194 195 slider.pausePlay.click(function(event) { 196 event.preventDefault(); 197 ($(this).hasClass('pause'))? slider.pause() : slider.resume(); 198 }); 199 } 200 ////////////////////////////////////////////////////////////////// 201 202 ////////////////////////////////////////////////////////////////// 203 //FlexSlider:Touch Swip Gestures 204 //Credit of concept: TouchSwipe - http://www.netcu.de/jquery-touchwipe-iphone-ipad-library 205 if (slider.vars.touchSwipe && 'ontouchstart' in document.documentElement) { 206 slider.each(function() { 207 var startX, 208 min_move_x = 20; 209 isMoving = false;
210 211 function cancelTouch() { 212 this.removeEventListener('touchmove', onTouchMove); 213 startX = null; 214 isMoving = false; 215 } 216 function onTouchMove(e) { 217 if (isMoving) { 218 var x = e.touches[0].pageX, 219 dx = startX - x; 220 221 if(Math.abs(dx) >= min_move_x) { 222 cancelTouch(); 223 var target = (dx > 0) ? slider.getTarget('next') : slider.getTarget('prev'); 224 225 if (slider.canAdvance(target)) { 226 slider.flexAnimate(target, slider.vars.pauseOnAction); 227 } 228 } 229 } 230 } 231 function onTouchStart(e) { 232 if (e.touches.length == 1) { 233 startX = e.touches[0].pageX; 234 isMoving = true; 235 this.addEventListener('touchmove', onTouchMove, false); 236 } 237 } 238 if ('ontouchstart' in document.documentElement) { 239 this.addEventListener('touchstart', onTouchStart, false); 240 } 241 }); 242 } 243 ////////////////////////////////////////////////////////////////// 244 245 ////////////////////////////////////////////////////////////////// 246 //FlexSlider: Resize Functions (If necessary) 247 if (slider.vars.animation.toLowerCase() == "slide") { 248 slider.sliderTimer; 249 $(window).resize(function(){ 250 slider.newSlides.width(slider.width()); 251 slider.container.width(((slider.count + slider.cloneCount) * slider.width()) + 2000); //extra width to account for quirks 252 253 //Slider resize reset 254 clearTimeout(slider.sliderTimer); 255 slider.sliderTimer = setTimeout(function(){ 256 slider.flexAnimate(slider.currentSlide); 257 }, 300); 258 }); 259 } 260 ////////////////////////////////////////////////////////////////// 261 262 //FlexSlider: start() Callback 263 slider.vars.start(slider); 264 } 265 266 //FlexSlider: Animation Actions 267 slider.flexAnimate = function(target, pause) { 268 if (!slider.animating) { 269 //Animating flag 270 slider.animating = true; 271 272 //FlexSlider: before() animation Callback 273 slider.animatingTo = target; 274 slider.vars.before(slider); 275 276 //Optional paramter to pause slider when making an anmiation call 277 if (pause) { 278 slider.pause(); 279 } 280 281 //Update controlNav 282 if (slider.vars.controlNav) { 283 slider.controlNav.removeClass('active').eq(target).addClass('active'); 284 } 285 286 //Is the slider at either end 287 slider.atEnd = (target == 0 || target == slider.count - 1) ? true : false; 288 if (!slider.vars.animationLoop && slider.vars.directionNav) { 289 if (target == 0) { 290 slider.directionNav.removeClass('disabled').filter('.prev').addClass('disabled'); 291 } else if (target == slider.count - 1) { 292 slider.directionNav.removeClass('disabled').filter('.next').addClass('disabled'); 293 } else { 294 slider.directionNav.removeClass('disabled'); 295 } 296 } 297 298 if (!slider.vars.animationLoop && target == slider.count - 1) { 299 slider.pause(); 300 //FlexSlider: end() of cycle Callback 301 slider.vars.end(slider); 302 } 303 304 if (slider.vars.animation.toLowerCase() == "slide") { 305 306 if (slider.currentSlide == 0 && target == slider.count - 1 && slider.vars.animationLoop && slider.direction != "next") { 307 slider.slideString = "0px"; 308 } else if (slider.currentSlide == slider.count - 1 && target == 0 && slider.vars.animationLoop && slider.direction != "prev") { 309 slider.slideString = (-1 * (slider.count + 1)) * slider.slides.filter(':first').width() + "px"; 310 } else { 311 slider.slideString = (-1 * (target + slider.cloneOffset)) * slider.slides.filter(':first').width() + "px"; 312 } 313 slider.container.animate({"marginLeft": slider.slideString}, slider.vars.animationDuration, function(){ 314 //Jump the slider if necessary 315 if (slider.currentSlide == 0 && target == slider.count - 1 && slider.vars.animationLoop) { 316 slider.container.css({"marginLeft": (-1 * slider.count) * slider.slides.filter(':first').width() + "px"}); 317 } else if (slider.currentSlide == slider.count - 1 && target == 0 && slider.vars.animationLoop) { 318 slider.container.css({"marginLeft": -1 * slider.slides.filter(':first').width() + "px"}); 319 } 320 slider.animating = false;
321 slider.currentSlide = target; 322 //FlexSlider: after() animation Callback 323 slider.vars.after(slider); 324 }); 325 } else { //Default to Fade 326 slider.slides.eq(slider.currentSlide).fadeOut(slider.vars.animationDuration); 327 slider.slides.eq(target).fadeIn(slider.vars.animationDuration, function() { 328 slider.animating = false; 329 slider.currentSlide = target; 330 //FlexSlider: after() animation Callback 331 slider.vars.after(slider); 332 }); 333 } 334 } 335 } 336 337 //FlexSlider: Automatic Slideshow 338 slider.animateSlides = function() { 339 if (!slider.animating) { 340 var target = (slider.currentSlide == slider.count - 1) ? 0 : slider.currentSlide + 1; 341 slider.flexAnimate(target); 342 } 343 } 344 345 //FlexSlider: Automatic Slideshow Pause 346 slider.pause = function() { 347 clearInterval(slider.animatedSlides); 348 if (slider.vars.pausePlay) { 349 slider.pausePlay.removeClass('pause').addClass('play').text(slider.vars.playText); 350 } 351 } 352 353 //FlexSlider: Automatic Slideshow Start/Resume 354 slider.resume = function() { 355 slider.animatedSlides = setInterval(slider.animateSlides, slider.vars.slideshowSpeed); 356 if (slider.vars.pausePlay) { 357 slider.pausePlay.removeClass('play').addClass('pause').text(slider.vars.pauseText); 358 } 359 } 360 361 //FlexSlider: Helper function for non-looping sliders 362 slider.canAdvance = function(target) { 363 if (!slider.vars.animationLoop && slider.atEnd) { 364 if (slider.currentSlide == 0 && target == slider.count - 1 && slider.direction != "next") { 365 return false; 366 } else if (slider.currentSlide == slider.count - 1 && target == 0 && slider.direction == "next") { 367 return false; 368 } else { 369 return true; 370 } 371 } else { 372 return true; 373 } 374 } 375 376 //FlexSlider: Helper function to determine animation target 377 slider.getTarget = function(dir) { 378 slider.direction = dir; 379 if (dir == "next") { 380 return (slider.currentSlide == slider.count - 1) ? 0 : slider.currentSlide + 1; 381 } else { 382 return (slider.currentSlide == 0) ? slider.count - 1 : slider.currentSlide - 1; 383 } 384 } 385 386 //FlexSlider: Initialize 387 slider.init(); 388 } 389 390 //FlexSlider: Default Settings 391 $.flexslider.defaults = { 392 animation: "fade", //Select your animation type (fade/slide) 393 slideshow: true, //Should the slider animate automatically by default? (true/false) 394 slideshowSpeed: 7000, //Set the speed of the slideshow cycling, in milliseconds 395 animationDuration: 2000, //Set the speed of animations, in milliseconds 396 directionNav: true, //Create navigation for previous/next navigation? (true/false) 397 controlNav: true, //Create navigation for paging control of each clide? (true/false) 398 keyboardNav: true, //Allow for keyboard navigation using left/right keys (true/false) 399 touchSwipe: true, //Touch swipe gestures for left/right slide navigation (true/false) 400 prevText: "Previous", //Set the text for the "previous" directionNav item 401 nextText: "Next", //Set the text for the "next" directionNav item 402 pausePlay: false, //Create pause/play dynamic element (true/false) 403 pauseText: 'Pause', //Set the text for the "pause" pausePlay item 404 playText: 'Play', //Set the text for the "play" pausePlay item 405 randomize: false, //Randomize slide order on page load? (true/false) 406 slideToStart: 0, //The slide that the slider should start on. Array notation (0 = first slide) 407 animationLoop: true, //Should the animation loop? If false, directionNav will received disabled classes when at either end (true/false) 408 pauseOnAction: true, //Pause the slideshow when interacting with control elements, highly recommended. (true/false) 409 pauseOnHover: false, //Pause the slideshow when hovering over slider, then resume when no longer hovering (true/false) 410 controlsContainer: "", //Advanced property: Can declare which container the navigation elements should be appended too. Default container is the flexSlider element. Example use would be ".flexslider-container", "#container", etc. If the given element is not found, the default action will be taken. 411 manualControls: "", //Advanced property: Can declare custom control navigation. Example would be ".flex-control-nav" or "#tabs-nav", etc. The number of elements in your controlNav should match the number of slides/tabs (obviously). 412 start: function(){}, //Callback: function(slider) - Fires when the slider loads the first slide 413 before: function(){}, //Callback: function(slider) - Fires asynchronously with each slider animation 414 after: function(){}, //Callback: function(slider) - Fires after each slider animation completes 415 end: function(){} //Callback: function(slider) - Fires when the slider reaches the last slide (asynchronous) 416 } 417 418 //FlexSlider: Plugin Function 419 $.fn.flexslider = function(options) { 420 return this.each(function() { 421 if ($(this).find('.slides li').length == 1) { 422 $(this).find('.slides li').fadeIn(400); 423 } 424 else if ($(this).data('flexslider') != true) { 425 new $.flexslider($(this), options); 426 } 427 }); 428 } 429 430})(jQuery);
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.