jquery.flexslider.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. /*
  2. * jQuery FlexSlider v1.4
  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. * TouchWipe gesture credits: http://www.netcu.de/jquery-touchwipe-iphone-ipad-library
  10. */
  11. (function ($) {
  12. $.fn.extend({
  13. flexslider: function(options) {
  14. //Plugin options and their default values
  15. var defaults = {
  16. animation: "fade", //Select your animation type (fade/slide/show)
  17. slideshow: true, //Should the slider animate automatically by default? (true/false)
  18. slideshowSpeed: 7000, //Set the speed of the slideshow cycling, in milliseconds
  19. animationDuration: 500, //Set the speed of animations, in milliseconds
  20. directionNav: true, //Create navigation for previous/next navigation? (true/false)
  21. controlNav: true, //Create navigation for paging control of each clide? (true/false)
  22. keyboardNav: true, //Allow for keyboard navigation using left/right keys (true/false)
  23. touchSwipe: true, //Touch swipe gestures for left/right slide navigation (true/false)
  24. prevText: "Previous", //Set the text for the "previous" directionNav item
  25. nextText: "Next", //Set the text for the "next" directionNav item
  26. randomize: false, //Randomize slide order on page load? (true/false)
  27. slideToStart: 0, //The slide that the slider should start on. Array notation (0 = first slide)
  28. pauseOnAction: true, //Pause the slideshow when interacting with control elements, highly recommended. (true/false)
  29. pauseOnHover: false, //Pause the slideshow when hovering over slider, then resume when no longer hovering (true/false)
  30. 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.
  31. 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).
  32. }
  33. //Get slider, slides, and other useful variables
  34. var options = $.extend(defaults, options),
  35. slider = this,
  36. container = $('.slides', slider),
  37. slides = $('.slides li', slider),
  38. length = slides.length;
  39. ANIMATING = false,
  40. currentSlide = options.slideToStart;
  41. ///////////////////////////////////////////////////////////////////
  42. // FLEXSLIDER: RANDOMIZE SLIDES
  43. if (options.randomize && length > 1) {
  44. slides.sort(function() { return (Math.round(Math.random())-0.5); });
  45. container.empty().append(slides);
  46. }
  47. ///////////////////////////////////////////////////////////////////
  48. //Slider animation initialize
  49. if (options.animation.toLowerCase() == "slide" && length > 1) {
  50. slider.css({"overflow": "hidden"});
  51. container.append(slides.filter(':first').clone().addClass('clone')).prepend(slides.filter(':last').clone().addClass('clone'));
  52. container.width(((length + 2) * slider.width()) + 2000); //extra width to account for quirks
  53. //Timeout function to give browser enough time to get proper width initially
  54. var newSlides = $('.slides li', slider);
  55. setTimeout(function() {
  56. newSlides.width(slider.width()).css({"float": "left"}).show();
  57. }, 100);
  58. container.css({"marginLeft": (-1 * (currentSlide + 1))* slider.width() + "px"});
  59. } else { //Default to fade
  60. slides.hide().eq(currentSlide).fadeIn(400);
  61. }
  62. ///////////////////////////////////////////////////////////////////
  63. // FLEXSLIDER: ANIMATION TYPE
  64. function flexAnimate(target) {
  65. if (!ANIMATING) {
  66. ANIMATING = true;
  67. if (options.animation.toLowerCase() == "slide") {
  68. if (currentSlide == 0 && target == length - 1) {
  69. container.animate({"marginLeft": "0px"}, options.animationDuration, function(){
  70. container.css({"marginLeft": (-1 * length) * slides.filter(':first').width() + "px"});
  71. ANIMATING = false;
  72. currentSlide = target;
  73. });
  74. } else if (currentSlide == length - 1 && target == 0) {
  75. container.animate({"marginLeft": (-1 * (length + 1)) * slides.filter(':first').width() + "px"}, options.animationDuration, function(){
  76. container.css({"marginLeft": -1 * slides.filter(':first').width() + "px"});
  77. ANIMATING = false;
  78. currentSlide = target;
  79. });
  80. } else {
  81. container.animate({"marginLeft": (-1 * (target + 1)) * slides.filter(':first').width() + "px"}, options.animationDuration, function(){
  82. ANIMATING = false;
  83. currentSlide = target;
  84. });
  85. }
  86. } else if (options.animation.toLowerCase() == "show") {
  87. slides.eq(currentSlide).hide();
  88. slides.eq(target).show();
  89. ANIMATING = false;
  90. currentSlide = target;
  91. } else { //Default to Fade
  92. slider.css({"minHeight": slides.eq(currentSlide).height()});
  93. slides.eq(currentSlide).fadeOut(options.animationDuration, function() {
  94. slides.eq(target).fadeIn(options.animationDuration, function() {
  95. ANIMATING = false;
  96. currentSlide = target;
  97. });
  98. slider.css({"minHeight": "inherit"});
  99. });
  100. }
  101. }
  102. }
  103. ///////////////////////////////////////////////////////////////////
  104. ///////////////////////////////////////////////////////////////////
  105. // FLEXSLIDER: CONTROL NAV
  106. if (options.controlNav && length > 1) {
  107. if (options.manualControls != "" && $(options.manualControls).length > 0) {
  108. var controlNav = $(options.manualControls);
  109. } else {
  110. var controlNav = $('<ol class="flex-control-nav"></ol>');
  111. var j = 1;
  112. for (var i = 0; i < length; i++) {
  113. controlNav.append('<li><a>' + j + '</a></li>');
  114. j++;
  115. }
  116. //extra children check for jquery 1.3.2 - Drupal 6
  117. if (options.controlsContainer != "" && $(options.controlsContainer).length > 0) {
  118. $(options.controlsContainer).append(controlNav);
  119. } else {
  120. slider.append(controlNav);
  121. }
  122. controlNav = $('.flex-control-nav li a');
  123. }
  124. controlNav.eq(currentSlide).addClass('active');
  125. controlNav.click(function(event) {
  126. event.preventDefault();
  127. if ($(this).hasClass('active') || ANIMATING) {
  128. return;
  129. } else {
  130. controlNav.removeClass('active');
  131. $(this).addClass('active');
  132. var selected = controlNav.index($(this));
  133. flexAnimate(selected);
  134. if (options.pauseOnAction) {
  135. clearInterval(animatedSlides);
  136. }
  137. }
  138. });
  139. }
  140. ///////////////////////////////////////////////////////////////////
  141. //////////////////////////////////////////////////////////////////
  142. //FLEXSLIDER: DIRECTION NAV
  143. if (options.directionNav && length > 1) {
  144. //Create and append the nav
  145. if (options.controlsContainer != "" && $(options.controlsContainer).length > 0) {
  146. $(options.controlsContainer).append($('<ul class="flex-direction-nav"><li><a class="prev" href="#">' + options.prevText + '</a></li><li><a class="next" href="#">' + options.nextText + '</a></li></ul>'));
  147. } else {
  148. slider.append($('<ul class="flex-direction-nav"><li><a class="prev" href="#">' + options.prevText + '</a></li><li><a class="next" href="#">' + options.nextText + '</a></li></ul>'));
  149. }
  150. $('.flex-direction-nav li a').click(function(event) {
  151. event.preventDefault();
  152. if (ANIMATING) {
  153. return;
  154. } else {
  155. if ($(this).hasClass('next')) {
  156. var target = (currentSlide == length - 1) ? 0 : currentSlide + 1;
  157. } else {
  158. var target = (currentSlide == 0) ? length - 1 : currentSlide - 1;
  159. }
  160. if (options.controlNav) {
  161. controlNav.removeClass('active');
  162. controlNav.eq(target).addClass('active');
  163. }
  164. flexAnimate(target);
  165. if (options.pauseOnAction) {
  166. clearInterval(animatedSlides);
  167. }
  168. }
  169. });
  170. }
  171. //////////////////////////////////////////////////////////////////
  172. //////////////////////////////////////////////////////////////////
  173. //FLEXSLIDER: KEYBOARD NAV
  174. if (options.keyboardNav && length > 1) {
  175. $(document).keyup(function(event) {
  176. if (ANIMATING) {
  177. return;
  178. } else if (event.keyCode != 39 && event.keyCode != 37){
  179. return;
  180. } else {
  181. if (event.keyCode == 39) {
  182. var target = (currentSlide == length - 1) ? 0 : currentSlide + 1;
  183. } else if (event.keyCode == 37){
  184. var target = (currentSlide == 0) ? length - 1 : currentSlide - 1;
  185. }
  186. if (options.controlNav) {
  187. controlNav.removeClass('active');
  188. controlNav.eq(target).addClass('active');
  189. }
  190. flexAnimate(target);
  191. if (options.pauseOnAction) {
  192. clearInterval(animatedSlides);
  193. }
  194. }
  195. });
  196. }
  197. //////////////////////////////////////////////////////////////////
  198. //////////////////////////////////////////////////////////////////
  199. //FLEXSLIDER: ANIMATION SLIDESHOW
  200. if (options.slideshow && length > 1) {
  201. var animatedSlides;
  202. function animateSlides() {
  203. if (ANIMATING) {
  204. return;
  205. } else {
  206. var target = (currentSlide == length - 1) ? 0 : currentSlide + 1;
  207. if (options.controlNav) {
  208. controlNav.removeClass('active');
  209. controlNav.eq(target).addClass('active');
  210. }
  211. flexAnimate(target);
  212. }
  213. }
  214. //pauseOnHover
  215. if (options.pauseOnHover) {
  216. slider.hover(function() {
  217. clearInterval(animatedSlides);
  218. }, function() {
  219. animatedSlides = setInterval(animateSlides, options.slideshowSpeed);
  220. });
  221. }
  222. //Initialize animation
  223. if (length > 1) {
  224. animatedSlides = setInterval(animateSlides, options.slideshowSpeed);
  225. }
  226. }
  227. //////////////////////////////////////////////////////////////////
  228. //////////////////////////////////////////////////////////////////
  229. //FLEXSLIDER: TOUCHSWIPE GESTURES
  230. //Credit of concept: TouchSwipe - http://www.netcu.de/jquery-touchwipe-iphone-ipad-library
  231. if (options.touchSwipe && 'ontouchstart' in document.documentElement && length > 1) {
  232. slider.each(function() {
  233. var startX,
  234. min_move_x = 20;
  235. isMoving = false;
  236. function cancelTouch() {
  237. this.removeEventListener('touchmove', onTouchMove);
  238. startX = null;
  239. isMoving = false;
  240. }
  241. function onTouchMove(e) {
  242. if (isMoving) {
  243. var x = e.touches[0].pageX,
  244. dx = startX - x;
  245. if(Math.abs(dx) >= min_move_x) {
  246. cancelTouch();
  247. if(dx > 0) {
  248. var target = (currentSlide == length - 1) ? 0 : currentSlide + 1;
  249. }
  250. else {
  251. var target = (currentSlide == 0) ? length - 1 : currentSlide - 1;
  252. }
  253. if (options.controlNav) {
  254. controlNav.removeClass('active');
  255. controlNav.eq(target).addClass('active');
  256. }
  257. flexAnimate(target);
  258. if (options.pauseOnAction) {
  259. clearInterval(animatedSlides);
  260. }
  261. }
  262. }
  263. }
  264. function onTouchStart(e) {
  265. if (e.touches.length == 1) {
  266. startX = e.touches[0].pageX;
  267. isMoving = true;
  268. this.addEventListener('touchmove', onTouchMove, false);
  269. }
  270. }
  271. if ('ontouchstart' in document.documentElement) {
  272. this.addEventListener('touchstart', onTouchStart, false);
  273. }
  274. });
  275. }
  276. //////////////////////////////////////////////////////////////////
  277. //////////////////////////////////////////////////////////////////
  278. //FLEXSLIDER: RESIZE FUNCTIONS (If necessary)
  279. if (options.animation.toLowerCase() == "slide" && length > 1) {
  280. var sliderTimer;
  281. $(window).resize(function(){
  282. newSlides.width(slider.width());
  283. //clones.width(slider.width());
  284. container.width(((length + 2) * slider.width()) + 2000); //extra width to account for quirks
  285. //slider resize reset
  286. clearTimeout(sliderTimer);
  287. sliderTimer = setTimeout(function(){
  288. flexAnimate(currentSlide);
  289. }, 300);
  290. });
  291. }
  292. //////////////////////////////////////////////////////////////////
  293. }
  294. });
  295. })(jQuery);