File indexing completed on 2024-05-19 06:00:31
0001 /** 0002 * Unslider by @idiot 0003 */ 0004 0005 (function($, f) { 0006 // If there's no jQuery, Unslider can't work, so kill the operation. 0007 if(!$) return f; 0008 0009 var Unslider = function() { 0010 // Set up our elements 0011 this.el = f; 0012 this.items = f; 0013 0014 // Dimensions 0015 this.sizes = []; 0016 this.max = [0,0]; 0017 0018 // Current inded 0019 this.current = 0; 0020 0021 // Start/stop timer 0022 this.interval = f; 0023 0024 // Set some options 0025 this.opts = { 0026 speed: 500, 0027 delay: 3000, // f for no autoplay 0028 complete: f, // when a slide's finished 0029 keys: !f, // keyboard shortcuts - disable if it breaks things 0030 dots: f, // display ••••o• pagination 0031 fluid: f // is it a percentage width?, 0032 }; 0033 0034 // Create a deep clone for methods where context changes 0035 var _ = this; 0036 0037 this.init = function(el, opts) { 0038 this.el = el; 0039 this.ul = el.children('ul'); 0040 this.max = [el.outerWidth(), el.outerHeight()]; 0041 this.items = this.ul.children('li').each(this.calculate); 0042 0043 // Check whether we're passing any options in to Unslider 0044 this.opts = $.extend(this.opts, opts); 0045 0046 // Set up the Unslider 0047 this.setup(); 0048 0049 return this; 0050 }; 0051 0052 // Get the width for an element 0053 // Pass a jQuery element as the context with .call(), and the index as a parameter: Unslider.calculate.call($('li:first'), 0) 0054 this.calculate = function(index) { 0055 var me = $(this), 0056 width = me.outerWidth(), height = me.outerHeight(); 0057 0058 // Add it to the sizes list 0059 _.sizes[index] = [width, height]; 0060 0061 // Set the max values 0062 if(width > _.max[0]) _.max[0] = width; 0063 if(height > _.max[1]) _.max[1] = height; 0064 }; 0065 0066 // Work out what methods need calling 0067 this.setup = function() { 0068 // Set the main element 0069 this.el.css({ 0070 overflow: 'hidden', 0071 width: _.max[0], 0072 height: this.items.first().outerHeight() 0073 }); 0074 0075 // Set the relative widths 0076 this.ul.css({width: (this.items.length * 100) + '%', position: 'relative'}); 0077 this.items.css('width', (100 / this.items.length) + '%'); 0078 0079 if(this.opts.delay !== f) { 0080 this.start(); 0081 this.el.hover(this.stop, this.start); 0082 } 0083 0084 // Custom keyboard support 0085 this.opts.keys && $(document).keydown(this.keys); 0086 0087 // Dot pagination 0088 this.opts.dots && this.dots(); 0089 0090 // Little patch for fluid-width sliders. Screw those guys. 0091 if(this.opts.fluid) { 0092 var resize = function() { 0093 _.el.css('width', Math.min(Math.round((_.el.outerWidth() / _.el.parent().outerWidth()) * 100), 100) + '%'); 0094 }; 0095 0096 resize(); 0097 $(window).resize(resize); 0098 } 0099 0100 if(this.opts.arrows) { 0101 this.el.parent().append('<p class="arrows"><span class="prev">â†</span><span class="next">→</span></p>') 0102 .find('.arrows span').click(function() { 0103 $.isFunction(_[this.className]) && _[this.className](); 0104 }); 0105 }; 0106 0107 // Swipe support 0108 if($.event.swipe) { 0109 this.el.on('swipeleft', _.prev).on('swiperight', _.next); 0110 } 0111 }; 0112 0113 // Move Unslider to a slide index 0114 this.move = function(index, cb) { 0115 // If it's out of bounds, go to the first slide 0116 if(!this.items.eq(index).length) index = 0; 0117 if(index < 0) index = (this.items.length - 1); 0118 0119 var target = this.items.eq(index); 0120 var obj = {height: target.outerHeight()}; 0121 var speed = cb ? 5 : this.opts.speed; 0122 0123 if(!this.ul.is(':animated')) { 0124 // Handle those pesky dots 0125 _.el.find('.dot:eq(' + index + ')').addClass('active').siblings().removeClass('active'); 0126 0127 this.el.animate(obj, speed) && this.ul.animate($.extend({left: '-' + index + '00%'}, obj), speed, function(data) { 0128 _.current = index; 0129 $.isFunction(_.opts.complete) && !cb && _.opts.complete(_.el); 0130 }); 0131 } 0132 }; 0133 0134 // Autoplay functionality 0135 this.start = function() { 0136 _.interval = setInterval(function() { 0137 _.move(_.current + 1); 0138 }, _.opts.delay); 0139 }; 0140 0141 // Stop autoplay 0142 this.stop = function() { 0143 _.interval = clearInterval(_.interval); 0144 return _; 0145 }; 0146 0147 // Keypresses 0148 this.keys = function(e) { 0149 var key = e.which; 0150 var map = { 0151 // Prev/next 0152 37: _.prev, 0153 39: _.next, 0154 0155 // Esc 0156 27: _.stop 0157 }; 0158 0159 if($.isFunction(map[key])) { 0160 map[key](); 0161 } 0162 }; 0163 0164 // Arrow navigation 0165 this.next = function() { return _.stop().move(_.current + 1) }; 0166 this.prev = function() { return _.stop().move(_.current - 1) }; 0167 0168 this.dots = function() { 0169 // Create the HTML 0170 var html = '<ol class="dots">'; 0171 $.each(this.items, function(index) { html += '<li class="dot' + (index < 1 ? ' active' : '') + '">' + (index + 1) + '</li>'; }); 0172 html += '</ol>'; 0173 0174 // Add it to the Unslider 0175 this.el.addClass('has-dots').append(html).find('.dot').click(function() { 0176 _.move($(this).index()); 0177 }); 0178 }; 0179 }; 0180 0181 // Create a jQuery plugin 0182 $.fn.unslider = function(o) { 0183 var len = this.length; 0184 0185 // Enable multiple-slider support 0186 return this.each(function(index) { 0187 // Cache a copy of $(this), so it 0188 var me = $(this); 0189 var instance = (new Unslider).init(me, o); 0190 0191 // Invoke an Unslider instance 0192 me.data('unslider' + (len > 1 ? '-' + (index + 1) : ''), instance); 0193 }); 0194 }; 0195 })(window.jQuery, false);