unslider.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /**
  2. * Unslider by @idiot
  3. */
  4. (function($, f) {
  5. // If there's no jQuery, Unslider can't work, so kill the operation.
  6. if(!$) return f;
  7. var Unslider = function() {
  8. // Set up our elements
  9. this.el = f;
  10. this.items = f;
  11. // Dimensions
  12. this.sizes = [];
  13. this.max = [0,0];
  14. // Current inded
  15. this.current = 0;
  16. // Start/stop timer
  17. this.interval = f;
  18. // Set some options
  19. this.opts = {
  20. speed: 500,
  21. delay: 3000, // f for no autoplay
  22. complete: f, // when a slide's finished
  23. keys: !f, // keyboard shortcuts - disable if it breaks things
  24. dots: f, // display ••••o• pagination
  25. fluid: f // is it a percentage width?,
  26. };
  27. // Create a deep clone for methods where context changes
  28. var _ = this;
  29. this.init = function(el, opts) {
  30. this.el = el;
  31. this.ul = el.children('ul');
  32. this.max = [el.outerWidth(), el.outerHeight()];
  33. this.items = this.ul.children('li').each(this.calculate);
  34. // Check whether we're passing any options in to Unslider
  35. this.opts = $.extend(this.opts, opts);
  36. // Set up the Unslider
  37. this.setup();
  38. return this;
  39. };
  40. // Get the width for an element
  41. // Pass a jQuery element as the context with .call(), and the index as a parameter: Unslider.calculate.call($('li:first'), 0)
  42. this.calculate = function(index) {
  43. var me = $(this),
  44. width = me.outerWidth(), height = me.outerHeight();
  45. // Add it to the sizes list
  46. _.sizes[index] = [width, height];
  47. // Set the max values
  48. if(width > _.max[0]) _.max[0] = width;
  49. if(height > _.max[1]) _.max[1] = height;
  50. };
  51. // Work out what methods need calling
  52. this.setup = function() {
  53. // Set the main element
  54. this.el.css({
  55. overflow: 'hidden',
  56. width: _.max[0],
  57. height: this.items.first().outerHeight()
  58. });
  59. // Set the relative widths
  60. this.ul.css({width: (this.items.length * 100) + '%', position: 'relative'});
  61. this.items.css('width', (100 / this.items.length) + '%');
  62. if(this.opts.delay !== f) {
  63. this.start();
  64. this.el.hover(this.stop, this.start);
  65. }
  66. // Custom keyboard support
  67. this.opts.keys && $(document).keydown(this.keys);
  68. // Dot pagination
  69. this.opts.dots && this.dots();
  70. // Little patch for fluid-width sliders. Screw those guys.
  71. if(this.opts.fluid) {
  72. var resize = function() {
  73. _.el.css('width', Math.min(Math.round((_.el.outerWidth() / _.el.parent().outerWidth()) * 100), 100) + '%');
  74. };
  75. resize();
  76. $(window).resize(resize);
  77. }
  78. if(this.opts.arrows) {
  79. this.el.parent().append('<p class="arrows"><span class="prev">←</span><span class="next">→</span></p>')
  80. .find('.arrows span').click(function() {
  81. $.isFunction(_[this.className]) && _[this.className]();
  82. });
  83. };
  84. // Swipe support
  85. if($.event.swipe) {
  86. this.el.on('swipeleft', _.prev).on('swiperight', _.next);
  87. }
  88. };
  89. // Move Unslider to a slide index
  90. this.move = function(index, cb) {
  91. // If it's out of bounds, go to the first slide
  92. if(!this.items.eq(index).length) index = 0;
  93. if(index < 0) index = (this.items.length - 1);
  94. var target = this.items.eq(index);
  95. var obj = {height: target.outerHeight()};
  96. var speed = cb ? 5 : this.opts.speed;
  97. if(!this.ul.is(':animated')) {
  98. // Handle those pesky dots
  99. _.el.find('.dot:eq(' + index + ')').addClass('active').siblings().removeClass('active');
  100. this.el.animate(obj, speed) && this.ul.animate($.extend({left: '-' + index + '00%'}, obj), speed, function(data) {
  101. _.current = index;
  102. $.isFunction(_.opts.complete) && !cb && _.opts.complete(_.el);
  103. });
  104. }
  105. };
  106. // Autoplay functionality
  107. this.start = function() {
  108. _.interval = setInterval(function() {
  109. _.move(_.current + 1);
  110. }, _.opts.delay);
  111. };
  112. // Stop autoplay
  113. this.stop = function() {
  114. _.interval = clearInterval(_.interval);
  115. return _;
  116. };
  117. // Keypresses
  118. this.keys = function(e) {
  119. var key = e.which;
  120. var map = {
  121. // Prev/next
  122. 37: _.prev,
  123. 39: _.next,
  124. // Esc
  125. 27: _.stop
  126. };
  127. if($.isFunction(map[key])) {
  128. map[key]();
  129. }
  130. };
  131. // Arrow navigation
  132. this.next = function() { return _.stop().move(_.current + 1) };
  133. this.prev = function() { return _.stop().move(_.current - 1) };
  134. this.dots = function() {
  135. // Create the HTML
  136. var html = '<ol class="dots">';
  137. $.each(this.items, function(index) { html += '<li class="dot' + (index < 1 ? ' active' : '') + '">' + (index + 1) + '</li>'; });
  138. html += '</ol>';
  139. // Add it to the Unslider
  140. this.el.addClass('has-dots').append(html).find('.dot').click(function() {
  141. _.move($(this).index());
  142. });
  143. };
  144. };
  145. // Create a jQuery plugin
  146. $.fn.unslider = function(o) {
  147. var len = this.length;
  148. // Enable multiple-slider support
  149. return this.each(function(index) {
  150. // Cache a copy of $(this), so it
  151. var me = $(this);
  152. var instance = (new Unslider).init(me, o);
  153. // Invoke an Unslider instance
  154. me.data('unslider' + (len > 1 ? '-' + (index + 1) : ''), instance);
  155. });
  156. };
  157. })(window.jQuery, false);