PluginProbe
Property Hive / 1.4.57
Property Hive v1.4.57
2.3.1 2.3.0 2.2.6 2.2.5 2.2.4 2.2.3 2.2.2 1.4.46 1.4.47 1.4.48 1.4.49 1.4.5 1.4.50 1.4.51 1.4.52 1.4.53 1.4.54 1.4.55 1.4.56 1.4.57 1.4.58 1.4.59 1.4.6 1.4.60 1.4.61 All 261 releases
propertyhive / assets / js / flexslider / jquery.flexslider.js

jquery.flexslider.js in Property Hive 1.4.57, at assets/js/flexslider/jquery.flexslider.js

1,168 lines 54.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /*
2 * jQuery FlexSlider v2.2.2
3 * Copyright 2012 WooThemes
4 * Contributing Author: Tyler Smith
5 * Customised version to include destroy method: https://github.com/fnagel/FlexSlider/blob/a9c8aa5e01352c472abf9d91b3e5dcb05888a8dc/jquery.flexslider.js
6 */
7 ;
8 (function ($) {
9
10 //FlexSlider: Object Instance
11 $.flexslider = function(el, options, instanceId) {
12 var slider = $(el);
13
14 // making variables public
15 slider.vars = $.extend({}, $.flexslider.defaults, options);
16
17 var namespace = slider.vars.namespace,
18 msGesture = window.navigator && window.navigator.msPointerEnabled && window.MSGesture,
19 touch = (( "ontouchstart" in window ) || msGesture || window.DocumentTouch && document instanceof DocumentTouch) && slider.vars.touch,
20 // depricating this idea, as devices are being released with both of these events
21 //eventType = (touch) ? "touchend" : "click",
22 eventType= "click" + slider.vars.eventNamespace + " touchend" + slider.vars.eventNamespace + " MSPointerUp" + slider.vars.eventNamespace,
23 watchedEvent = "",
24 watchedEventClearTimer,
25 vertical = slider.vars.direction === "vertical",
26 reverse = slider.vars.reverse,
27 carousel = (slider.vars.itemWidth > 0),
28 fade = slider.vars.animation === "fade",
29 asNav = slider.vars.asNavFor !== "",
30 methods = {},
31 focused = true;
32
33 var instanceId = ( typeof instanceId !== 'undefined' ) ? instanceId++ : 0
34
35 // Store a reference to the slider object
36 $.data(el, "flexslider", slider);
37
38 // Private slider methods
39 methods = {
40 init: function() {
41 slider.id = instanceId;
42 slider.animating = false;
43 // Get current slide and make sure it is a number
44 slider.currentSlide = parseInt( ( slider.vars.startAt ? slider.vars.startAt : 0), 10 );
45 if ( isNaN( slider.currentSlide ) ) slider.currentSlide = 0;
46 slider.animatingTo = slider.currentSlide;
47 slider.atEnd = (slider.currentSlide === 0 || slider.currentSlide === slider.last);
48 slider.containerSelector = slider.vars.selector.substr(0,slider.vars.selector.search(' '));
49 slider.slides = $(slider.vars.selector, slider);
50 slider.container = $(slider.containerSelector, slider);
51 slider.count = slider.slides.length;
52 // SYNC:
53 slider.syncExists = $(slider.vars.sync).length > 0;
54 // SLIDE:
55 if (slider.vars.animation === "slide") slider.vars.animation = "swing";
56 slider.prop = (vertical) ? "top" : "marginLeft";
57 slider.args = {};
58 // SLIDESHOW:
59 slider.manualPause = false;
60 slider.stopped = false;
61 //PAUSE WHEN INVISIBLE
62 slider.started = false;
63 slider.startTimeout = null;
64 // TOUCH/USECSS:
65 slider.transitions = !slider.vars.video && !fade && slider.vars.useCSS && (function() {
66 var obj = document.createElement('div'),
67 props = ['perspectiveProperty', 'WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective'];
68 for (var i in props) {
69 if ( obj.style[ props[i] ] !== undefined ) {
70 slider.pfx = props[i].replace('Perspective','').toLowerCase();
71 slider.prop = "-" + slider.pfx + "-transform";
72 return true;
73 }
74 }
75 return false;
76 }());
77 // CONTROLSCONTAINER:
78 if (slider.vars.controlsContainer !== "") slider.controlsContainer = $(slider.vars.controlsContainer).length > 0 && $(slider.vars.controlsContainer);
79 // MANUAL:
80 if (slider.vars.manualControls !== "") slider.manualControls = $(slider.vars.manualControls).length > 0 && $(slider.vars.manualControls);
81
82 // RANDOMIZE:
83 if (slider.vars.randomize) {
84 slider.slides.sort(function() { return (Math.round(Math.random())-0.5); });
85 slider.container.empty().append(slider.slides);
86 }
87
88 slider.doMath();
89
90 // INIT
91 slider.setup("init");
92
93 // CONTROLNAV:
94 if (slider.vars.controlNav) methods.controlNav.setup();
95
96 // DIRECTIONNAV:
97 if (slider.vars.directionNav) methods.directionNav.setup();
98
99 // KEYBOARD:
100 if (slider.vars.keyboard && ($(slider.containerSelector).length === 1 || slider.vars.multipleKeyboard)) {
101 $(document).bind('keyup' + slider.vars.eventNamespace + "-" + slider.id, function(event) {
102 var keycode = event.keyCode;
103 if (!slider.animating && (keycode === 39 || keycode === 37)) {
104 var target = (keycode === 39) ? slider.getTarget('next') :
105 (keycode === 37) ? slider.getTarget('prev') : false;
106 slider.flexAnimate(target, slider.vars.pauseOnAction);
107 }
108 });
109 }
110 // MOUSEWHEEL:
111 if (slider.vars.mousewheel) {
112 slider.bind('mousewheel' + slider.vars.eventNamespace, function(event, delta, deltaX, deltaY) {
113 event.preventDefault();
114 var target = (delta < 0) ? slider.getTarget('next') : slider.getTarget('prev');
115 slider.flexAnimate(target, slider.vars.pauseOnAction);
116 });
117 }
118
119 // PAUSEPLAY
120 if (slider.vars.pausePlay) methods.pausePlay.setup();
121
122 //PAUSE WHEN INVISIBLE
123 if (slider.vars.slideshow && slider.vars.pauseInvisible) methods.pauseInvisible.init();
124
125 // SLIDSESHOW
126 if (slider.vars.slideshow) {
127 if (slider.vars.pauseOnHover) {
128 slider.hover(function() {
129 if (!slider.manualPlay && !slider.manualPause) slider.pause();
130 }, function() {
131 if (!slider.manualPause && !slider.manualPlay && !slider.stopped) slider.play();
132 });
133 }
134 // initialize animation
135 //If we're visible, or we don't use PageVisibility API
136 if(!slider.vars.pauseInvisible || !methods.pauseInvisible.isHidden()) {
137 (slider.vars.initDelay > 0) ? slider.startTimeout = setTimeout(slider.play, slider.vars.initDelay) : slider.play();
138 }
139 }
140
141 // ASNAV:
142 if (asNav) methods.asNav.setup();
143
144 // TOUCH
145 if (touch && slider.vars.touch) methods.touch();
146
147 // FADE&&SMOOTHHEIGHT || SLIDE:
148 if (!fade || (fade && slider.vars.smoothHeight)) $(window).bind("resize" + slider.vars.eventNamespace + "-" + slider.id + " orientationchange" + slider.vars.eventNamespace + "-" + slider.id + " focus" + slider.vars.eventNamespace + "-" + slider.id, methods.resize);
149
150 slider.find("img").attr("draggable", "false");
151
152 // API: start() Callback
153 setTimeout(function(){
154 slider.vars.start(slider);
155 }, 200);
156 },
157 asNav: {
158 setup: function() {
159 slider.asNav = true;
160 slider.animatingTo = Math.floor(slider.currentSlide/slider.move);
161 slider.currentItem = slider.currentSlide;
162 slider.slides.removeClass(namespace + "active-slide").eq(slider.currentItem).addClass(namespace + "active-slide");
163 if(!msGesture){
164 slider.slides.on(eventType, function(e){
165 e.preventDefault();
166 var $slide = $(this),
167 target = $slide.index();
168 var posFromLeft = $slide.offset().left - $(slider).scrollLeft(); // Find position of slide relative to left of slider container
169 if( posFromLeft <= 0 && $slide.hasClass( namespace + 'active-slide' ) ) {
170 slider.flexAnimate(slider.getTarget("prev"), true);
171 } else if (!$(slider.vars.asNavFor).data('flexslider').animating && !$slide.hasClass(namespace + "active-slide")) {
172 slider.direction = (slider.currentItem < target) ? "next" : "prev";
173 slider.flexAnimate(target, slider.vars.pauseOnAction, false, true, true);
174 }
175 });
176 }else{
177 el._slider = slider;
178 slider.slides.each(function (){
179 var that = this;
180 that._gesture = new MSGesture();
181 that._gesture.target = that;
182 that.addEventListener("MSPointerDown", function (e){
183 e.preventDefault();
184 if(e.currentTarget._gesture)
185 e.currentTarget._gesture.addPointer(e.pointerId);
186 }, false);
187 that.addEventListener("MSGestureTap", function (e){
188 e.preventDefault();
189 var $slide = $(this),
190 target = $slide.index();
191 if (!$(slider.vars.asNavFor).data('flexslider').animating && !$slide.hasClass('active')) {
192 slider.direction = (slider.currentItem < target) ? "next" : "prev";
193 slider.flexAnimate(target, slider.vars.pauseOnAction, false, true, true);
194 }
195 });
196 });
197 }
198 }
199 },
200 controlNav: {
201 setup: function() {
202 if (!slider.manualControls) {
203 methods.controlNav.setupPaging();
204 } else { // MANUALCONTROLS:
205 methods.controlNav.setupManual();
206 }
207 },
208 setupPaging: function() {
209 var type = (slider.vars.controlNav === "thumbnails") ? 'control-thumbs' : 'control-paging',
210 j = 1,
211 item,
212 slide;
213
214 slider.controlNavScaffold = $('<ol class="'+ namespace + 'control-nav ' + namespace + type + '"></ol>');
215
216 if (slider.pagingCount > 1) {
217 for (var i = 0; i < slider.pagingCount; i++) {
218 slide = slider.slides.eq(i);
219 item = (slider.vars.controlNav === "thumbnails") ? '<img src="' + slide.attr( 'data-thumb' ) + '"/>' : '<a>' + j + '</a>';
220 if ( 'thumbnails' === slider.vars.controlNav && true === slider.vars.thumbCaptions ) {
221 var captn = slide.attr( 'data-thumbcaption' );
222 if ( '' != captn && undefined != captn ) item += '<span class="' + namespace + 'caption">' + captn + '</span>';
223 }
224 slider.controlNavScaffold.append('<li>' + item + '</li>');
225 j++;
226 }
227 }
228
229 // CONTROLSCONTAINER:
230 (slider.controlsContainer) ? $(slider.controlsContainer).append(slider.controlNavScaffold) : slider.append(slider.controlNavScaffold);
231 methods.controlNav.set();
232
233 methods.controlNav.active();
234
235 slider.controlNavScaffold.delegate('a, img', eventType, function(event) {
236 event.preventDefault();
237
238 if (watchedEvent === "" || watchedEvent === event.type) {
239 var $this = $(this),
240 target = slider.controlNav.index($this);
241
242 if (!$this.hasClass(namespace + 'active')) {
243 slider.direction = (target > slider.currentSlide) ? "next" : "prev";
244 slider.flexAnimate(target, slider.vars.pauseOnAction);
245 }
246 }
247
248 // setup flags to prevent event duplication
249 if (watchedEvent === "") {
250 watchedEvent = event.type;
251 }
252 methods.setToClearWatchedEvent();
253
254 });
255 },
256 setupManual: function() {
257 slider.controlNav = slider.manualControls;
258 methods.controlNav.active();
259
260 slider.controlNav.bind(eventType, function(event) {
261 event.preventDefault();
262
263 if (watchedEvent === "" || watchedEvent === event.type) {
264 var $this = $(this),
265 target = slider.controlNav.index($this);
266
267 if (!$this.hasClass(namespace + 'active')) {
268 (target > slider.currentSlide) ? slider.direction = "next" : slider.direction = "prev";
269 slider.flexAnimate(target, slider.vars.pauseOnAction);
270 }
271 }
272
273 // setup flags to prevent event duplication
274 if (watchedEvent === "") {
275 watchedEvent = event.type;
276 }
277 methods.setToClearWatchedEvent();
278 });
279 },
280 set: function() {
281 var selector = (slider.vars.controlNav === "thumbnails") ? 'img' : 'a';
282 slider.controlNav = $('.' + namespace + 'control-nav li ' + selector, (slider.controlsContainer) ? slider.controlsContainer : slider);
283 },
284 active: function() {
285 slider.controlNav.removeClass(namespace + "active").eq(slider.animatingTo).addClass(namespace + "active");
286 },
287 update: function(action, pos) {
288 if (slider.pagingCount > 1 && action === "add") {
289 slider.controlNavScaffold.append($('<li><a>' + slider.count + '</a></li>'));
290 } else if (slider.pagingCount === 1) {
291 slider.controlNavScaffold.find('li').remove();
292 } else {
293 slider.controlNav.eq(pos).closest('li').remove();
294 }
295 methods.controlNav.set();
296 (slider.pagingCount > 1 && slider.pagingCount !== slider.controlNav.length) ? slider.update(pos, action) : methods.controlNav.active();
297 }
298 },
299 directionNav: {
300 setup: function() {
301 var directionNavScaffold = $('<ul class="' + namespace + 'direction-nav"><li><a class="' + namespace + 'prev" href="#">' + slider.vars.prevText + '</a></li><li><a class="' + namespace + 'next" href="#">' + slider.vars.nextText + '</a></li></ul>');
302
303 // CONTROLSCONTAINER:
304 if (slider.controlsContainer) {
305 $(slider.controlsContainer).append(directionNavScaffold);
306 slider.directionNav = $('.' + namespace + 'direction-nav li a', slider.controlsContainer);
307 } else {
308 slider.append(directionNavScaffold);
309 slider.directionNav = $('.' + namespace + 'direction-nav li a', slider);
310 }
311
312 methods.directionNav.update();
313
314 slider.directionNav.bind(eventType, function(event) {
315 event.preventDefault();
316 var target;
317
318 if (watchedEvent === "" || watchedEvent === event.type) {
319 target = ($(this).hasClass(namespace + 'next')) ? slider.getTarget('next') : slider.getTarget('prev');
320 slider.flexAnimate(target, slider.vars.pauseOnAction);
321 }
322
323 // setup flags to prevent event duplication
324 if (watchedEvent === "") {
325 watchedEvent = event.type;
326 }
327 methods.setToClearWatchedEvent();
328 });
329 },
330 update: function() {
331 var disabledClass = namespace + 'disabled';
332 if (slider.pagingCount === 1) {
333 slider.directionNav.addClass(disabledClass).attr('tabindex', '-1');
334 } else if (!slider.vars.animationLoop) {
335 if (slider.animatingTo === 0) {
336 slider.directionNav.removeClass(disabledClass).filter('.' + namespace + "prev").addClass(disabledClass).attr('tabindex', '-1');
337 } else if (slider.animatingTo === slider.last) {
338 slider.directionNav.removeClass(disabledClass).filter('.' + namespace + "next").addClass(disabledClass).attr('tabindex', '-1');
339 } else {
340 slider.directionNav.removeClass(disabledClass).removeAttr('tabindex');
341 }
342 } else {
343 slider.directionNav.removeClass(disabledClass).removeAttr('tabindex');
344 }
345 }
346 },
347 pausePlay: {
348 setup: function() {
349 var pausePlayScaffold = $('<div class="' + namespace + 'pauseplay"><a></a></div>');
350
351 // CONTROLSCONTAINER:
352 if (slider.controlsContainer) {
353 slider.controlsContainer.append(pausePlayScaffold);
354 slider.pausePlay = $('.' + namespace + 'pauseplay a', slider.controlsContainer);
355 } else {
356 slider.append(pausePlayScaffold);
357 slider.pausePlay = $('.' + namespace + 'pauseplay a', slider);
358 }
359
360 methods.pausePlay.update((slider.vars.slideshow) ? namespace + 'pause' : namespace + 'play');
361
362 slider.pausePlay.bind(eventType, function(event) {
363 event.preventDefault();
364
365 if (watchedEvent === "" || watchedEvent === event.type) {
366 if ($(this).hasClass(namespace + 'pause')) {
367 slider.manualPause = true;
368 slider.manualPlay = false;
369 slider.pause();
370 } else {
371 slider.manualPause = false;
372 slider.manualPlay = true;
373 slider.play();
374 }
375 }
376
377 // setup flags to prevent event duplication
378 if (watchedEvent === "") {
379 watchedEvent = event.type;
380 }
381 methods.setToClearWatchedEvent();
382 });
383 },
384 update: function(state) {
385 (state === "play") ? slider.pausePlay.removeClass(namespace + 'pause').addClass(namespace + 'play').html(slider.vars.playText) : slider.pausePlay.removeClass(namespace + 'play').addClass(namespace + 'pause').html(slider.vars.pauseText);
386 }
387 },
388 touch: function() {
389 var startX,
390 startY,
391 offset,
392 cwidth,
393 dx,
394 startT,
395 scrolling = false,
396 localX = 0,
397 localY = 0,
398 accDx = 0;
399
400 if(!msGesture){
401 el.addEventListener('touchstart', onTouchStart, false);
402
403 function onTouchStart(e) {
404 if (slider.animating) {
405 e.preventDefault();
406 } else if ( ( window.navigator.msPointerEnabled ) || e.touches.length === 1 ) {
407 slider.pause();
408 // CAROUSEL:
409 cwidth = (vertical) ? slider.h : slider. w;
410 startT = Number(new Date());
411 // CAROUSEL:
412
413 // Local vars for X and Y points.
414 localX = e.touches[0].pageX;
415 localY = e.touches[0].pageY;
416
417 offset = (carousel && reverse && slider.animatingTo === slider.last) ? 0 :
418 (carousel && reverse) ? slider.limit - (((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo) :
419 (carousel && slider.currentSlide === slider.last) ? slider.limit :
420 (carousel) ? ((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.currentSlide :
421 (reverse) ? (slider.last - slider.currentSlide + slider.cloneOffset) * cwidth : (slider.currentSlide + slider.cloneOffset) * cwidth;
422 startX = (vertical) ? localY : localX;
423 startY = (vertical) ? localX : localY;
424
425 el.addEventListener('touchmove', onTouchMove, false);
426 el.addEventListener('touchend', onTouchEnd, false);
427 }
428 }
429
430 function onTouchMove(e) {
431 // Local vars for X and Y points.
432
433 localX = e.touches[0].pageX;
434 localY = e.touches[0].pageY;
435
436 dx = (vertical) ? startX - localY : startX - localX;
437 scrolling = (vertical) ? (Math.abs(dx) < Math.abs(localX - startY)) : (Math.abs(dx) < Math.abs(localY - startY));
438
439 var fxms = 500;
440
441 if ( ! scrolling || Number( new Date() ) - startT > fxms ) {
442 e.preventDefault();
443 if (!fade && slider.transitions) {
444 if (!slider.vars.animationLoop) {
445 dx = dx/((slider.currentSlide === 0 && dx < 0 || slider.currentSlide === slider.last && dx > 0) ? (Math.abs(dx)/cwidth+2) : 1);
446 }
447 slider.setProps(offset + dx, "setTouch");
448 }
449 }
450 }
451
452 function onTouchEnd(e) {
453 // finish the touch by undoing the touch session
454 el.removeEventListener('touchmove', onTouchMove, false);
455
456 if (slider.animatingTo === slider.currentSlide && !scrolling && !(dx === null)) {
457 var updateDx = (reverse) ? -dx : dx,
458 target = (updateDx > 0) ? slider.getTarget('next') : slider.getTarget('prev');
459
460 if (slider.canAdvance(target) && (Number(new Date()) - startT < 550 && Math.abs(updateDx) > 50 || Math.abs(updateDx) > cwidth/2)) {
461 slider.flexAnimate(target, slider.vars.pauseOnAction);
462 } else {
463 if (!fade) slider.flexAnimate(slider.currentSlide, slider.vars.pauseOnAction, true);
464 }
465 }
466 el.removeEventListener('touchend', onTouchEnd, false);
467
468 startX = null;
469 startY = null;
470 dx = null;
471 offset = null;
472 }
473 }else{
474 el.style.msTouchAction = "none";
475 el._gesture = new MSGesture();
476 el._gesture.target = el;
477 el.addEventListener("MSPointerDown", onMSPointerDown, false);
478 el._slider = slider;
479 el.addEventListener("MSGestureChange", onMSGestureChange, false);
480 el.addEventListener("MSGestureEnd", onMSGestureEnd, false);
481
482 function onMSPointerDown(e){
483 e.stopPropagation();
484 if (slider.animating) {
485 e.preventDefault();
486 }else{
487 slider.pause();
488 el._gesture.addPointer(e.pointerId);
489 accDx = 0;
490 cwidth = (vertical) ? slider.h : slider. w;
491 startT = Number(new Date());
492 // CAROUSEL:
493
494 offset = (carousel && reverse && slider.animatingTo === slider.last) ? 0 :
495 (carousel && reverse) ? slider.limit - (((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo) :
496 (carousel && slider.currentSlide === slider.last) ? slider.limit :
497 (carousel) ? ((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.currentSlide :
498 (reverse) ? (slider.last - slider.currentSlide + slider.cloneOffset) * cwidth : (slider.currentSlide + slider.cloneOffset) * cwidth;
499 }
500 }
501
502 function onMSGestureChange(e) {
503 e.stopPropagation();
504 var slider = e.target._slider;
505 if(!slider){
506 return;
507 }
508 var transX = -e.translationX,
509 transY = -e.translationY;
510
511 //Accumulate translations.
512 accDx = accDx + ((vertical) ? transY : transX);
513 dx = accDx;
514 scrolling = (vertical) ? (Math.abs(accDx) < Math.abs(-transX)) : (Math.abs(accDx) < Math.abs(-transY));
515
516 if(e.detail === e.MSGESTURE_FLAG_INERTIA){
517 setImmediate(function (){
518 el._gesture.stop();
519 });
520
521 return;
522 }
523
524 if (!scrolling || Number(new Date()) - startT > 500) {
525 e.preventDefault();
526 if (!fade && slider.transitions) {
527 if (!slider.vars.animationLoop) {
528 dx = accDx / ((slider.currentSlide === 0 && accDx < 0 || slider.currentSlide === slider.last && accDx > 0) ? (Math.abs(accDx) / cwidth + 2) : 1);
529 }
530 slider.setProps(offset + dx, "setTouch");
531 }
532 }
533 }
534
535 function onMSGestureEnd(e) {
536 e.stopPropagation();
537 var slider = e.target._slider;
538 if(!slider){
539 return;
540 }
541 if (slider.animatingTo === slider.currentSlide && !scrolling && !(dx === null)) {
542 var updateDx = (reverse) ? -dx : dx,
543 target = (updateDx > 0) ? slider.getTarget('next') : slider.getTarget('prev');
544
545 if (slider.canAdvance(target) && (Number(new Date()) - startT < 550 && Math.abs(updateDx) > 50 || Math.abs(updateDx) > cwidth/2)) {
546 slider.flexAnimate(target, slider.vars.pauseOnAction);
547 } else {
548 if (!fade) slider.flexAnimate(slider.currentSlide, slider.vars.pauseOnAction, true);
549 }
550 }
551
552 startX = null;
553 startY = null;
554 dx = null;
555 offset = null;
556 accDx = 0;
557 }
558 }
559 },
560 resize: function() {
561 if (!slider.animating && slider.is(':visible')) {
562 if (!carousel) slider.doMath();
563
564 if (fade) {
565 // SMOOTH HEIGHT:
566 methods.smoothHeight();
567 } else if (carousel) { //CAROUSEL:
568 slider.slides.width(slider.computedW);
569 slider.update(slider.pagingCount);
570 slider.setProps();
571 }
572 else if (vertical) { //VERTICAL:
573 slider.viewport.height(slider.h);
574 slider.setProps(slider.h, "setTotal");
575 } else {
576 // SMOOTH HEIGHT:
577 if (slider.vars.smoothHeight) methods.smoothHeight();
578 slider.newSlides.width(slider.computedW);
579 slider.setProps(slider.computedW, "setTotal");
580 }
581 }
582 },
583 smoothHeight: function(dur) {
584 if (!vertical || fade) {
585 var $obj = (fade) ? slider : slider.viewport;
586 (dur) ? $obj.animate({"height": slider.slides.eq(slider.animatingTo).height()}, dur) : $obj.height(slider.slides.eq(slider.animatingTo).height());
587 }
588 },
589 sync: function(action) {
590 var $obj = $(slider.vars.sync).data("flexslider"),
591 target = slider.animatingTo;
592
593 switch (action) {
594 case "animate": $obj.flexAnimate(target, slider.vars.pauseOnAction, false, true); break;
595 case "play": if (!$obj.playing && !$obj.asNav) { $obj.play(); } break;
596 case "pause": $obj.pause(); break;
597 }
598 },
599 uniqueID: function($clone) {
600 $clone.find( '[id]' ).each(function() {
601 var $this = $(this);
602 $this.attr( 'id', $this.attr( 'id' ) + '_clone' );
603 });
604 return $clone;
605 },
606 pauseInvisible: {
607 visProp: null,
608 init: function() {
609 var prefixes = ['webkit','moz','ms','o'];
610
611 if ('hidden' in document) return 'hidden';
612 for (var i = 0; i < prefixes.length; i++) {
613 if ((prefixes[i] + 'Hidden') in document)
614 methods.pauseInvisible.visProp = prefixes[i] + 'Hidden';
615 }
616 if (methods.pauseInvisible.visProp) {
617 var evtname = methods.pauseInvisible.visProp.replace(/[H|h]idden/,'') + 'visibilitychange';
618 document.addEventListener(evtname, function() {
619 if (methods.pauseInvisible.isHidden()) {
620 if(slider.startTimeout) clearTimeout(slider.startTimeout); //If clock is ticking, stop timer and prevent from starting while invisible
621 else slider.pause(); //Or just pause
622 }
623 else {
624 if(slider.started) slider.play(); //Initiated before, just play
625 else (slider.vars.initDelay > 0) ? setTimeout(slider.play, slider.vars.initDelay) : slider.play(); //Didn't init before: simply init or wait for it
626 }
627 });
628 }
629 },
630 isHidden: function() {
631 return document[methods.pauseInvisible.visProp] || false;
632 }
633 },
634 setToClearWatchedEvent: function() {
635 clearTimeout(watchedEventClearTimer);
636 watchedEventClearTimer = setTimeout(function() {
637 watchedEvent = "";
638 }, 3000);
639 }
640 };
641
642 // public methods
643 slider.flexAnimate = function(target, pause, override, withSync, fromNav) {
644 if (!slider.vars.animationLoop && target !== slider.currentSlide) {
645 slider.direction = (target > slider.currentSlide) ? "next" : "prev";
646 }
647
648 if (asNav && slider.pagingCount === 1) slider.direction = (slider.currentItem < target) ? "next" : "prev";
649
650 if (!slider.animating && (slider.canAdvance(target, fromNav) || override) && slider.is(":visible")) {
651 if (asNav && withSync) {
652 var master = $(slider.vars.asNavFor).data('flexslider');
653 slider.atEnd = target === 0 || target === slider.count - 1;
654 master.flexAnimate(target, true, false, true, fromNav);
655 slider.direction = (slider.currentItem < target) ? "next" : "prev";
656 master.direction = slider.direction;
657
658 if (Math.ceil((target + 1)/slider.visible) - 1 !== slider.currentSlide && target !== 0) {
659 slider.currentItem = target;
660 slider.slides.removeClass(namespace + "active-slide").eq(target).addClass(namespace + "active-slide");
661 target = Math.floor(target/slider.visible);
662 } else {
663 slider.currentItem = target;
664 slider.slides.removeClass(namespace + "active-slide").eq(target).addClass(namespace + "active-slide");
665 return false;
666 }
667 }
668
669 slider.animating = true;
670 slider.animatingTo = target;
671
672 // SLIDESHOW:
673 if (pause) slider.pause();
674
675 // API: before() animation Callback
676 slider.vars.before(slider);
677
678 // SYNC:
679 if (slider.syncExists && !fromNav) methods.sync("animate");
680
681 // CONTROLNAV
682 if (slider.vars.controlNav) methods.controlNav.active();
683
684 // !CAROUSEL:
685 // CANDIDATE: slide active class (for add/remove slide)
686 if (!carousel) slider.slides.removeClass(namespace + 'active-slide').eq(target).addClass(namespace + 'active-slide');
687
688 // INFINITE LOOP:
689 // CANDIDATE: atEnd
690 slider.atEnd = target === 0 || target === slider.last;
691
692 // DIRECTIONNAV:
693 if (slider.vars.directionNav) methods.directionNav.update();
694
695 if (target === slider.last) {
696 // API: end() of cycle Callback
697 slider.vars.end(slider);
698 // SLIDESHOW && !INFINITE LOOP:
699 if (!slider.vars.animationLoop) slider.pause();
700 }
701
702 // SLIDE:
703 if (!fade) {
704 var dimension = (vertical) ? slider.slides.filter(':first').height() : slider.computedW,
705 margin, slideString, calcNext;
706
707 // INFINITE LOOP / REVERSE:
708 if (carousel) {
709 //margin = (slider.vars.itemWidth > slider.w) ? slider.vars.itemMargin * 2 : slider.vars.itemMargin;
710 margin = slider.vars.itemMargin;
711 calcNext = ((slider.itemW + margin) * slider.move) * slider.animatingTo;
712 slideString = (calcNext > slider.limit && slider.visible !== 1) ? slider.limit : calcNext;
713 } else if (slider.currentSlide === 0 && target === slider.count - 1 && slider.vars.animationLoop && slider.direction !== "next") {
714 slideString = (reverse) ? (slider.count + slider.cloneOffset) * dimension : 0;
715 } else if (slider.currentSlide === slider.last && target === 0 && slider.vars.animationLoop && slider.direction !== "prev") {
716 slideString = (reverse) ? 0 : (slider.count + 1) * dimension;
717 } else {
718 slideString = (reverse) ? ((slider.count - 1) - target + slider.cloneOffset) * dimension : (target + slider.cloneOffset) * dimension;
719 }
720 slider.setProps(slideString, "", slider.vars.animationSpeed);
721 if (slider.transitions) {
722 if (!slider.vars.animationLoop || !slider.atEnd) {
723 slider.animating = false;
724 slider.currentSlide = slider.animatingTo;
725 }
726 slider.container.unbind("webkitTransitionEnd" + slider.vars.eventNamespace + " transitionend" + slider.vars.eventNamespace);
727 slider.container.bind("webkitTransitionEnd" + slider.vars.eventNamespace + " transitionend" + slider.vars.eventNamespace, function() {
728 slider.wrapup(dimension);
729 });
730 } else {
731 slider.container.animate(slider.args, slider.vars.animationSpeed, slider.vars.easing, function(){
732 slider.wrapup(dimension);
733 });
734 }
735 } else { // FADE:
736 if (!touch) {
737 //slider.slides.eq(slider.currentSlide).fadeOut(slider.vars.animationSpeed, slider.vars.easing);
738 //slider.slides.eq(target).fadeIn(slider.vars.animationSpeed, slider.vars.easing, slider.wrapup);
739
740 slider.slides.eq(slider.currentSlide).css({"zIndex": 1}).animate({"opacity": 0}, slider.vars.animationSpeed, slider.vars.easing);
741 slider.slides.eq(target).css({"zIndex": 2}).animate({"opacity": 1}, slider.vars.animationSpeed, slider.vars.easing, slider.wrapup);
742
743 } else {
744 slider.slides.eq(slider.currentSlide).css({ "opacity": 0, "zIndex": 1 });
745 slider.slides.eq(target).css({ "opacity": 1, "zIndex": 2 });
746 slider.wrapup(dimension);
747 }
748 }
749 // SMOOTH HEIGHT:
750 if (slider.vars.smoothHeight) methods.smoothHeight(slider.vars.animationSpeed);
751 }
752 };
753 slider.wrapup = function(dimension) {
754 // SLIDE:
755 if (!fade && !carousel) {
756 if (slider.currentSlide === 0 && slider.animatingTo === slider.last && slider.vars.animationLoop) {
757 slider.setProps(dimension, "jumpEnd");
758 } else if (slider.currentSlide === slider.last && slider.animatingTo === 0 && slider.vars.animationLoop) {
759 slider.setProps(dimension, "jumpStart");
760 }
761 }
762 slider.animating = false;
763 slider.currentSlide = slider.animatingTo;
764 // API: after() animation Callback
765 slider.vars.after(slider);
766 };
767
768 // SLIDESHOW:
769 slider.animateSlides = function() {
770 if (!slider.animating && focused ) slider.flexAnimate(slider.getTarget("next"));
771 };
772 // SLIDESHOW:
773 slider.pause = function() {
774 clearInterval(slider.animatedSlides);
775 slider.animatedSlides = null;
776 slider.playing = false;
777 // PAUSEPLAY:
778 if (slider.vars.pausePlay) methods.pausePlay.update("play");
779 // SYNC:
780 if (slider.syncExists) methods.sync("pause");
781 };
782 // SLIDESHOW:
783 slider.play = function() {
784 if (slider.playing) clearInterval(slider.animatedSlides);
785 slider.animatedSlides = slider.animatedSlides || setInterval(slider.animateSlides, slider.vars.slideshowSpeed);
786 slider.started = slider.playing = true;
787 // PAUSEPLAY:
788 if (slider.vars.pausePlay) methods.pausePlay.update("pause");
789 // SYNC:
790 if (slider.syncExists) methods.sync("play");
791 };
792 // STOP:
793 slider.stop = function () {
794 slider.pause();
795 slider.stopped = true;
796 };
797 slider.canAdvance = function(target, fromNav) {
798 // ASNAV:
799 var last = (asNav) ? slider.pagingCount - 1 : slider.last;
800 return (fromNav) ? true :
801 (asNav && slider.currentItem === slider.count - 1 && target === 0 && slider.direction === "prev") ? true :
802 (asNav && slider.currentItem === 0 && target === slider.pagingCount - 1 && slider.direction !== "next") ? false :
803 (target === slider.currentSlide && !asNav) ? false :
804 (slider.vars.animationLoop) ? true :
805 (slider.atEnd && slider.currentSlide === 0 && target === last && slider.direction !== "next") ? false :
806 (slider.atEnd && slider.currentSlide === last && target === 0 && slider.direction === "next") ? false :
807 true;
808 };
809 slider.getTarget = function(dir) {
810 slider.direction = dir;
811 if (dir === "next") {
812 return (slider.currentSlide === slider.last) ? 0 : slider.currentSlide + 1;
813 } else {
814 return (slider.currentSlide === 0) ? slider.last : slider.currentSlide - 1;
815 }
816 };
817
818 // SLIDE:
819 slider.setProps = function(pos, special, dur) {
820 var target = (function() {
821 var posCheck = (pos) ? pos : ((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo,
822 posCalc = (function() {
823 if (carousel) {
824 return (special === "setTouch") ? pos :
825 (reverse && slider.animatingTo === slider.last) ? 0 :
826 (reverse) ? slider.limit - (((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo) :
827 (slider.animatingTo === slider.last) ? slider.limit : posCheck;
828 } else {
829 switch (special) {
830 case "setTotal": return (reverse) ? ((slider.count - 1) - slider.currentSlide + slider.cloneOffset) * pos : (slider.currentSlide + slider.cloneOffset) * pos;
831 case "setTouch": return (reverse) ? pos : pos;
832 case "jumpEnd": return (reverse) ? pos : slider.count * pos;
833 case "jumpStart": return (reverse) ? slider.count * pos : pos;
834 default: return pos;
835 }
836 }
837 }());
838
839 return (posCalc * -1) + "px";
840 }());
841
842 if (slider.transitions) {
843 target = (vertical) ? "translate3d(0," + target + ",0)" : "translate3d(" + target + ",0,0)";
844 dur = (dur !== undefined) ? (dur/1000) + "s" : "0s";
845 slider.container.css("-" + slider.pfx + "-transition-duration", dur);
846 slider.container.css("transition-duration", dur);
847 }
848
849 slider.args[slider.prop] = target;
850 if (slider.transitions || dur === undefined) slider.container.css(slider.args);
851
852 slider.container.css('transform',target);
853 };
854
855 slider.setup = function(type) {
856 // SLIDE:
857 if (!fade) {
858 var sliderOffset, arr;
859
860 if (type === "init") {
861 slider.viewport = $('<div class="' + namespace + 'viewport"></div>').css({"overflow": "hidden", "position": "relative"}).appendTo(slider).append(slider.container);
862 // INFINITE LOOP:
863 slider.cloneCount = 0;
864 slider.cloneOffset = 0;
865 // REVERSE:
866 if (reverse) {
867 arr = $.makeArray(slider.slides).reverse();
868 slider.slides = $(arr);
869 slider.container.empty().append(slider.slides);
870 }
871 }
872 // INFINITE LOOP && !CAROUSEL:
873 if (slider.vars.animationLoop && !carousel) {
874 slider.cloneCount = 2;
875 slider.cloneOffset = 1;
876 // clear out old clones
877 if (type !== "init") slider.container.find('.clone').remove();
878 slider.container.append(slider.slides.first().clone().addClass('clone').attr('aria-hidden', 'true')).prepend(slider.slides.last().clone().addClass('clone').attr('aria-hidden', 'true'));
879 methods.uniqueID( slider.slides.first().clone().addClass('clone') ).appendTo( slider.container );
880 methods.uniqueID( slider.slides.last().clone().addClass('clone') ).prependTo( slider.container );
881 }
882 slider.newSlides = $(slider.vars.selector, slider);
883
884 sliderOffset = (reverse) ? slider.count - 1 - slider.currentSlide + slider.cloneOffset : slider.currentSlide + slider.cloneOffset;
885 // VERTICAL:
886 if (vertical && !carousel) {
887 slider.container.height((slider.count + slider.cloneCount) * 200 + "%").css("position", "absolute").width("100%");
888 setTimeout(function(){
889 slider.newSlides.css({"display": "block"});
890 slider.doMath();
891 slider.viewport.height(slider.h);
892 slider.setProps(sliderOffset * slider.h, "init");
893 }, (type === "init") ? 100 : 0);
894 } else {
895 slider.container.width((slider.count + slider.cloneCount) * 200 + "%");
896 slider.setProps(sliderOffset * slider.computedW, "init");
897 setTimeout(function(){
898 slider.doMath();
899 slider.newSlides.css({"width": slider.computedW, "float": "left", "display": "block"});
900 // SMOOTH HEIGHT:
901 if (slider.vars.smoothHeight) methods.smoothHeight();
902 }, (type === "init") ? 100 : 0);
903 }
904 } else { // FADE:
905 slider.slides.css({"width": "100%", "float": "left", "marginRight": "-100%", "position": "relative"});
906 if (type === "init") {
907 if (!touch) {
908 //slider.slides.eq(slider.currentSlide).fadeIn(slider.vars.animationSpeed, slider.vars.easing);
909 slider.slides.css({ "opacity": 0, "display": "block", "zIndex": 1 }).eq(slider.currentSlide).css({"zIndex": 2}).animate({"opacity": 1},slider.vars.animationSpeed,slider.vars.easing);
910 } else {
911 slider.slides.css({ "opacity": 0, "display": "block", "webkitTransition": "opacity " + slider.vars.animationSpeed / 1000 + "s ease", "zIndex": 1 }).eq(slider.currentSlide).css({ "opacity": 1, "zIndex": 2});
912 }
913 }
914 // SMOOTH HEIGHT:
915 if (slider.vars.smoothHeight) methods.smoothHeight();
916 }
917 // !CAROUSEL:
918 // CANDIDATE: active slide
919 if (!carousel) slider.slides.removeClass(namespace + "active-slide").eq(slider.currentSlide).addClass(namespace + "active-slide");
920
921 //FlexSlider: init() Callback
922 slider.vars.init(slider);
923 };
924
925 slider.doMath = function() {
926 var slide = slider.slides.first(),
927 slideMargin = slider.vars.itemMargin,
928 minItems = slider.vars.minItems,
929 maxItems = slider.vars.maxItems;
930
931 slider.w = (slider.viewport===undefined) ? slider.width() : slider.viewport.width();
932 slider.h = slide.height();
933 slider.boxPadding = slide.outerWidth() - slide.width();
934
935 // CAROUSEL:
936 if (carousel) {
937 slider.itemT = slider.vars.itemWidth + slideMargin;
938 slider.minW = (minItems) ? minItems * slider.itemT : slider.w;
939 slider.maxW = (maxItems) ? (maxItems * slider.itemT) - slideMargin : slider.w;
940 slider.itemW = (slider.minW > slider.w) ? (slider.w - (slideMargin * (minItems - 1)))/minItems :
941 (slider.maxW < slider.w) ? (slider.w - (slideMargin * (maxItems - 1)))/maxItems :
942 (slider.vars.itemWidth > slider.w) ? slider.w : slider.vars.itemWidth;
943
944 slider.visible = Math.floor(slider.w/(slider.itemW));
945 slider.move = (slider.vars.move > 0 && slider.vars.move < slider.visible ) ? slider.vars.move : slider.visible;
946 slider.pagingCount = Math.ceil(((slider.count - slider.visible)/slider.move) + 1);
947 slider.last = slider.pagingCount - 1;
948 slider.limit = (slider.pagingCount === 1) ? 0 :
949 (slider.vars.itemWidth > slider.w) ? (slider.itemW * (slider.count - 1)) + (slideMargin * (slider.count - 1)) : ((slider.itemW + slideMargin) * slider.count) - slider.w - slideMargin;
950 } else {
951 slider.itemW = slider.w;
952 slider.pagingCount = slider.count;
953 slider.last = slider.count - 1;
954 }
955 slider.computedW = slider.itemW - slider.boxPadding;
956 };
957
958 slider.update = function(pos, action) {
959 slider.doMath();
960
961 // update currentSlide and slider.animatingTo if necessary
962 if (!carousel) {
963 if (pos < slider.currentSlide) {
964 slider.currentSlide += 1;
965 } else if (pos <= slider.currentSlide && pos !== 0) {
966 slider.currentSlide -= 1;
967 }
968 slider.animatingTo = slider.currentSlide;
969 }
970
971 // update controlNav
972 if (slider.vars.controlNav && !slider.manualControls) {
973 if ((action === "add" && !carousel) || slider.pagingCount > slider.controlNav.length) {
974 methods.controlNav.update("add");
975 } else if ((action === "remove" && !carousel) || slider.pagingCount < slider.controlNav.length) {
976 if (carousel && slider.currentSlide > slider.last) {
977 slider.currentSlide -= 1;
978 slider.animatingTo -= 1;
979 }
980 methods.controlNav.update("remove", slider.last);
981 }
982 }
983 // update directionNav
984 if (slider.vars.directionNav) methods.directionNav.update();
985
986 };
987
988 slider.addSlide = function(obj, pos) {
989 var $obj = $(obj);
990
991 slider.count += 1;
992 slider.last = slider.count - 1;
993
994 // append new slide
995 if (vertical && reverse) {
996 (pos !== undefined) ? slider.slides.eq(slider.count - pos).after($obj) : slider.container.prepend($obj);
997 } else {
998 (pos !== undefined) ? slider.slides.eq(pos).before($obj) : slider.container.append($obj);
999 }
1000
1001 // update currentSlide, animatingTo, controlNav, and directionNav
1002 slider.update(pos, "add");
1003
1004 // update slider.slides
1005 slider.slides = $(slider.vars.selector + ':not(.clone)', slider);
1006 // re-setup the slider to accomdate new slide
1007 slider.setup();
1008
1009 //FlexSlider: added() Callback
1010 slider.vars.added(slider);
1011 };
1012 slider.removeSlide = function(obj) {
1013 var pos = (isNaN(obj)) ? slider.slides.index($(obj)) : obj;
1014
1015 // update count
1016 slider.count -= 1;
1017 slider.last = slider.count - 1;
1018
1019 // remove slide
1020 if (isNaN(obj)) {
1021 $(obj, slider.slides).remove();
1022 } else {
1023 (vertical && reverse) ? slider.slides.eq(slider.last).remove() : slider.slides.eq(obj).remove();
1024 }
1025
1026 // update currentSlide, animatingTo, controlNav, and directionNav
1027 slider.doMath();
1028 slider.update(pos, "remove");
1029
1030 // update slider.slides
1031 slider.slides = $(slider.vars.selector + ':not(.clone)', slider);
1032 // re-setup the slider to accomdate new slide
1033 slider.setup();
1034
1035 // FlexSlider: removed() Callback
1036 slider.vars.removed(slider);
1037 };
1038
1039 slider.destroy = function() {
1040 var classNamespace = '.' + slider.vars.namespace; // Namespaced class selector
1041 if (slider.vars.controlNav) slider.controlNav.closest(classNamespace + 'control-nav').remove(); // Remove control elements if present
1042 if (slider.vars.directionNav) slider.directionNav.closest(classNamespace + 'direction-nav').remove(); // Remove direction-nav elements if present
1043 if (slider.vars.pausePlay) slider.pausePlay.closest(classNamespace + 'pauseplay').remove(); // Remove pauseplay elements if present
1044 slider.find('.clone').remove(); // Remove any flexslider clones
1045 slider.unbind(slider.vars.eventNamespace); // Remove events on slider
1046 if ( slider.vars.animation != "fade" ) slider.container.unwrap(); // Remove the .flex-viewport div
1047 slider.container.removeAttr('style') // Remove generated CSS (could collide with 3rd parties)
1048 slider.container.unbind(slider.vars.eventNamespace); // Remove events on slider
1049 slider.slides.removeAttr('style'); // Remove generated CSS (could collide with 3rd parties)
1050 slider.slides.filter(classNamespace + 'active-slide').removeClass(slider.vars.namespace + 'active-slide'); // Remove slide active class
1051 slider.slides.unbind(slider.vars.eventNamespace); // Remove events on slides
1052 $(document).unbind(slider.vars.eventNamespace + "-" + slider.id); // Remove events from document for this instance only
1053 $(window).unbind(slider.vars.eventNamespace + "-" + slider.id); // Remove events from window for this instance only
1054 slider.stop(); // Stop the interval
1055 slider.removeData('flexslider'); // Remove data
1056 }
1057
1058 //FlexSlider: Initialize
1059 methods.init();
1060 };
1061
1062 // Ensure the slider isn't focussed if the window loses focus.
1063 $( window ).blur( function ( e ) {
1064 focused = false;
1065 }).focus( function ( e ) {
1066 focused = true;
1067 });
1068
1069 //FlexSlider: Default Settings
1070 $.flexslider.defaults = {
1071 namespace: "flex-", //{NEW} String: Prefix string attached to the class of every element generated by the plugin
1072 eventNamespace: '.flexslider', //{NEW} String: Event namespace string attached to all element events generated by the plugin. The period at the start of the string is required.
1073 selector: ".slides > li", //{NEW} Selector: Must match a simple pattern. '{container} > {slide}' -- Ignore pattern at your own peril
1074 animation: "fade", //String: Select your animation type, "fade" or "slide"
1075 easing: "swing", //{NEW} String: Determines the easing method used in jQuery transitions. jQuery easing plugin is supported!
1076 direction: "horizontal", //String: Select the sliding direction, "horizontal" or "vertical"
1077 reverse: false, //{NEW} Boolean: Reverse the animation direction
1078 animationLoop: true, //Boolean: Should the animation loop? If false, directionNav will received "disable" classes at either end
1079 smoothHeight: false, //{NEW} Boolean: Allow height of the slider to animate smoothly in horizontal mode
1080 startAt: 0, //Integer: The slide that the slider should start on. Array notation (0 = first slide)
1081 slideshow: true, //Boolean: Animate slider automatically
1082 slideshowSpeed: 7000, //Integer: Set the speed of the slideshow cycling, in milliseconds
1083 animationSpeed: 600, //Integer: Set the speed of animations, in milliseconds
1084 initDelay: 0, //{NEW} Integer: Set an initialization delay, in milliseconds
1085 randomize: false, //Boolean: Randomize slide order
1086 thumbCaptions: false, //Boolean: Whether or not to put captions on thumbnails when using the "thumbnails" controlNav.
1087
1088 // Usability features
1089 pauseOnAction: true, //Boolean: Pause the slideshow when interacting with control elements, highly recommended.
1090 pauseOnHover: false, //Boolean: Pause the slideshow when hovering over slider, then resume when no longer hovering
1091 pauseInvisible: true, //{NEW} Boolean: Pause the slideshow when tab is invisible, resume when visible. Provides better UX, lower CPU usage.
1092 useCSS: true, //{NEW} Boolean: Slider will use CSS3 transitions if available
1093 touch: true, //{NEW} Boolean: Allow touch swipe navigation of the slider on touch-enabled devices
1094 video: false, //{NEW} Boolean: If using video in the slider, will prevent CSS3 3D Transforms to avoid graphical glitches
1095
1096 // Primary Controls
1097 controlNav: true, //Boolean: Create navigation for paging control of each clide? Note: Leave true for manualControls usage
1098 directionNav: true, //Boolean: Create navigation for previous/next navigation? (true/false)
1099 prevText: "Previous", //String: Set the text for the "previous" directionNav item
1100 nextText: "Next", //String: Set the text for the "next" directionNav item
1101
1102 // Secondary Navigation
1103 keyboard: true, //Boolean: Allow slider navigating via keyboard left/right keys
1104 multipleKeyboard: false, //{NEW} Boolean: Allow keyboard navigation to affect multiple sliders. Default behavior cuts out keyboard navigation with more than one slider present.
1105 mousewheel: false, //{UPDATED} Boolean: Requires jquery.mousewheel.js (https://github.com/brandonaaron/jquery-mousewheel) - Allows slider navigating via mousewheel
1106 pausePlay: false, //Boolean: Create pause/play dynamic element
1107 pauseText: "Pause", //String: Set the text for the "pause" pausePlay item
1108 playText: "Play", //String: Set the text for the "play" pausePlay item
1109
1110 // Special properties
1111 controlsContainer: "", //{UPDATED} jQuery Object/Selector: Declare which container the navigation elements should be appended too. Default container is the FlexSlider element. Example use would be $(".flexslider-container"). Property is ignored if given element is not found.
1112 manualControls: "", //{UPDATED} jQuery Object/Selector: Declare custom control navigation. Examples would be $(".flex-control-nav li") or "#tabs-nav li img", etc. The number of elements in your controlNav should match the number of slides/tabs.
1113 sync: "", //{NEW} Selector: Mirror the actions performed on this slider with another slider. Use with care.
1114 asNavFor: "", //{NEW} Selector: Internal property exposed for turning the slider into a thumbnail navigation for another slider
1115
1116 // Carousel Options
1117 itemWidth: 0, //{NEW} Integer: Box-model width of individual carousel items, including horizontal borders and padding.
1118 itemMargin: 0, //{NEW} Integer: Margin between carousel items.
1119 minItems: 1, //{NEW} Integer: Minimum number of carousel items that should be visible. Items will resize fluidly when below this.
1120 maxItems: 0, //{NEW} Integer: Maxmimum number of carousel items that should be visible. Items will resize fluidly when above this limit.
1121 move: 0, //{NEW} Integer: Number of carousel items that should move on animation. If 0, slider will move all visible items.
1122 allowOneSlide: true, //{NEW} Boolean: Whether or not to allow a slider comprised of a single slide
1123
1124 // Callback API
1125 start: function(){}, //Callback: function(slider) - Fires when the slider loads the first slide
1126 before: function(){}, //Callback: function(slider) - Fires asynchronously with each slider animation
1127 after: function(){}, //Callback: function(slider) - Fires after each slider animation completes
1128 end: function(){}, //Callback: function(slider) - Fires when the slider reaches the last slide (asynchronous)
1129 added: function(){}, //{NEW} Callback: function(slider) - Fires after a slide is added
1130 removed: function(){}, //{NEW} Callback: function(slider) - Fires after a slide is removed
1131 init: function() {} //{NEW} Callback: function(slider) - Fires after the slider is initially setup
1132 };
1133
1134 var instanceId = 0;
1135
1136 //FlexSlider: Plugin Function
1137 $.fn.flexslider = function(options) {
1138 if (options === undefined) options = {};
1139
1140 if (typeof options === "object") {
1141 return this.each(function() {
1142 var $this = $(this),
1143 selector = (options.selector) ? options.selector : ".slides > li",
1144 $slides = $this.find(selector);
1145
1146 if ( ( $slides.length === 1 && options.allowOneSlide === true ) || $slides.length === 0 ) {
1147 $slides.fadeIn(400);
1148 if (options.start) options.start($this);
1149 } else if ($this.data('flexslider') === undefined) {
1150 new $.flexslider(this, options, instanceId++);
1151 }
1152 });
1153 } else {
1154 // Helper strings to quickly perform functions on the slider
1155 var $slider = $(this).data('flexslider');
1156 switch (options) {
1157 case "play": $slider.play(); break;
1158 case "pause": $slider.pause(); break;
1159 case "stop": $slider.stop(); break;
1160 case "next": $slider.flexAnimate($slider.getTarget("next"), true); break;
1161 case "prev":
1162 case "previous": $slider.flexAnimate($slider.getTarget("prev"), true); break;
1163 case "destroy": $slider.destroy(); break;
1164 default: if (typeof options === "number") $slider.flexAnimate(options, true);
1165 }
1166 }
1167 };
1168 })(jQuery);