diff --git a/dist/css/unslider.css b/dist/css/unslider.css index 4bb2f73..79efe15 100644 --- a/dist/css/unslider.css +++ b/dist/css/unslider.css @@ -1 +1 @@ -.unslider{overflow:auto}.unslider-wrap{position:relative}.unslider-wrap.unslider-carousel li{float:left}.unslider-fade{position:relative}.unslider-fade .unslider-wrap li{position:absolute;left:0;top:0;right:0;z-index:8}.unslider-fade .unslider-wrap li.unslider-active{z-index:10}.unslider li{list-style:none;margin:0;padding:0;border:none}.unslider-arrow{position:absolute;left:20px;z-index:2;cursor:pointer}.unslider-arrow.next{left:auto;right:20px} \ No newline at end of file +.unslider{overflow:auto}.unslider-wrap{position:relative}.unslider-wrap.unslider-carousel li{float:left}.unslider-vertical>ul{height:100%}.unslider-vertical li{float:none;width:100%}.unslider-fade{position:relative}.unslider-fade .unslider-wrap li{position:absolute;left:0;top:0;right:0;z-index:8}.unslider-fade .unslider-wrap li.unslider-active{z-index:10}.unslider li{list-style:none;margin:0;padding:0;border:none}.unslider-arrow{position:absolute;left:20px;z-index:2;cursor:pointer}.unslider-arrow.next{left:auto;right:20px} \ No newline at end of file diff --git a/dist/js/unslider-min.js b/dist/js/unslider-min.js index 79dbcf0..3e02045 100644 --- a/dist/js/unslider-min.js +++ b/dist/js/unslider-min.js @@ -1 +1 @@ -!function($){return $?($.Unslider=function(t,n){var e=this;return e._="unslider",e.defaults={autoplay:!1,delay:3e3,speed:750,easing:"swing",keys:{prev:37,next:39},nav:!0,arrows:{prev:'',next:''},animation:"horizontal",selectors:{container:"ul:first",slides:"li"},animateHeight:!1,activeClass:e._+"-active",swipe:!0},e.$context=t,e.options={},e.$parent=null,e.$container=null,e.$slides=null,e.$nav=null,e.$arrows=[],e.total=0,e.current=0,e.prefix=e._+"-",e.eventSuffix="."+e.prefix+~~(2e3*Math.random()),e.interval=null,e.init=function(t){return e.options=$.extend({},e.defaults,t),e.$container=e.$context.find(e.options.selectors.container).addClass(e.prefix+"wrap"),e.$slides=e.$container.children(e.options.selectors.slides),e.setup(),["nav","arrows","keys","infinite"].forEach(function(t){e.options[t]&&e["init"+$._ucfirst(t)]()}),void 0!==typeof jQuery.event.special.swipe&&e.options.swipe&&e.initSwipe(),e.options.autoplay&&e.start(),e.calculateSlides(),e.$context.trigger(e._+".ready"),e.animate(e.options.index||e.current,"init")},e.setup=function(){e.$context.addClass(e.prefix+"slider "+e.prefix+e.options.animation).wrap('
'),e.$parent=e.$context.parent("."+e._);var t=e.$context.css("position");"static"===t&&e.$context.css("position","relative"),e.$context.css("overflow","hidden")},e.calculateSlides=function(){e.total=e.$slides.length,"fade"!==e.options.animation&&(e.$container.css("width",100*e.total+"%").addClass(e.prefix+"carousel"),e.$slides.css("width",100/e.total+"%"))},e.start=function(){return e.interval=setTimeout(function(){e.next(),e.start()},e.options.delay),e},e.stop=function(){return clearTimeout(e.interval),e},e.initNav=function(){var t=$('');e.$slides.each(function(n){var i=this.getAttribute("data-nav")||n+1;$.isFunction(e.options.nav)&&(i=e.options.nav.call(e.$slides.eq(n),n,i)),t.children("ol").append('
  • '+i+"
  • ")}),e.$nav=t.insertAfter(e.$context),e.$nav.find("li").on("click"+e.eventSuffix,function(){var t=$(this).addClass(e.options.activeClass);t.siblings().removeClass(e.options.activeClass),e.animate(t.attr("data-slide"))})},e.initArrows=function(){e.options.arrows===!0&&(e.options.arrows=e.defaults.arrows),$.each(e.options.arrows,function(t,n){e.$arrows.push($(n).insertAfter(e.$context).on("click"+e.eventSuffix,e[t]))})},e.initKeys=function(){e.options.keys===!0&&(e.options.keys=e.defaults.keys),$(document).on("keyup"+e.eventSuffix,function(t){$.each(e.options.keys,function(n,i){t.which===i&&$.isFunction(e[n])&&e[n].call(e)})})},e.initSwipe=function(){var t=e.$slides.width();e.$container.on({swipeleft:e.next,swiperight:e.prev,movestart:function(t){return t.distX>t.distY&&t.distX<-t.distY||t.distX-t.distY?!!t.preventDefault():void e.$container.css("position","relative")}}),"fade"!==e.options.animation&&e.$container.on({move:function(n){e.$container.css("left",-(100*e.current)+100*n.distX/t+"%")},moveend:function(n){return Math.abs(n.distX)/t<$.event.special.swipe.settings.threshold?e._move(e.$container,{left:-(100*e.current)+"%"},!1,200):void 0}})},e.initInfinite=function(){var t=["first","last"];t.forEach(function(n,i){e.$slides.push.apply(e.$slides,e.$slides.filter(':not(".'+e._+'-cloned")')[n]().clone().addClass(e._+"-cloned")["insert"+(0===i?"After":"Before")](e.$slides[t[~~!i]]()))}),e.$container.css("margin-left","-100%")},e.destroyArrows=function(){e.$arrows.forEach(function(t){t.remove()})},e.destroySwipe=function(){e.$container.off("movestart swipeleft move moveend").css("left",0)},e.destroyKeys=function(){$(document).off("keyup"+e.eventSuffix)},e.setIndex=function(t){return 0>t&&(t=e.total-1),e.current=Math.min(Math.max(0,t),e.total-1),e.options.nav&&e.$nav.find('[data-slide="'+e.current+'"]')._toggleActive(e.options.activeClass),e.$slides.eq(e.current)._toggleActive(e.options.activeClass),e},e.animate=function(t,n){if("first"===t&&(t=0),"last"===t&&(t=e.total),isNaN(t))return e;e.options.autoplay&&e.stop().start(),e.setIndex(t),e.$context.trigger(e._+".change",[t,e.$slides.eq(t)]);var i="animate"+$._ucfirst(e.options.animation);return $.isFunction(e[i])&&e[i](e.current,n),e},e.next=function(){var t=e.current+1;return t>=e.total&&(t=0),e.animate(t,"next")},e.prev=function(){return e.animate(e.current-1,"prev")},e.animateHorizontal=function(t){if(e.options.animateHeight&&e._move(e.$context,{height:e.$slides.eq(t).height()},!1),e.options.infinite){var n;t===e.total-1&&(n=e.total-3,t=-1),t===e.total-2&&(n=0,t=e.total-2),"number"==typeof n&&(e.setIndex(n),e.$context.on(e._+".moved",function(){e.current===n&&e.$container.css("left",-(100*n)+"%").off(e._+".moved")}))}return e._move(e.$container,{left:-(100*t)+"%"})},e.animateFade=function(t){var n=e.$slides.eq(t).addClass(e.options.activeClass);e._move(n.siblings().removeClass(e.options.activeClass),{opacity:0}),e._move(n,{opacity:1},!1)},e._move=function(t,n,i,s){return i!==!1&&(i=function(){e.$context.trigger(e._+".moved")}),t._move(n,s||e.options.speed,e.options.easing,i)},e.init(n)},$.fn._toggleActive=function(t){return this.addClass(t).siblings().removeClass(t)},$._ucfirst=function(t){return t.toString().toLowerCase().replace(/^./,function(t){return t.toUpperCase()})},$.fn._move=function(){return this.stop(!0,!0),$.fn.velocity?$.fn.velocity.apply(this,arguments):$.fn.animate.apply(this,arguments)},void($.fn.unslider=function(t){return this.each(function(){var n=$(this);if("string"==typeof t&&n.data("unslider")){t=t.split(":");var e=t[0],i=n.data("unslider")[e];if(t[1]){var s=t[1].split(",");return $.isFunction(i)&&i.apply(n,s)}return $.isFunction(i)&&i(),this}return n.data("unslider",new $.Unslider(n,t))})})):console.warn("Unslider needs jQuery")}(window.jQuery); \ No newline at end of file +!function($){return $?($.Unslider=function(t,n){var e=this;return e._="unslider",e.defaults={autoplay:!1,delay:3e3,speed:750,easing:"swing",keys:{prev:37,next:39},nav:!0,arrows:{prev:'',next:''},animation:"horizontal",selectors:{container:"ul:first",slides:"li"},animateHeight:!1,activeClass:e._+"-active",swipe:!0},e.$context=t,e.options={},e.$parent=null,e.$container=null,e.$slides=null,e.$nav=null,e.$arrows=[],e.total=0,e.current=0,e.prefix=e._+"-",e.eventSuffix="."+e.prefix+~~(2e3*Math.random()),e.interval=null,e.init=function(t){return e.options=$.extend({},e.defaults,t),e.$container=e.$context.find(e.options.selectors.container).addClass(e.prefix+"wrap"),e.$slides=e.$container.children(e.options.selectors.slides),e.setup(),["nav","arrows","keys","infinite"].forEach(function(t){e.options[t]&&e["init"+$._ucfirst(t)]()}),void 0!==typeof jQuery.event.special.swipe&&e.options.swipe&&e.initSwipe(),e.options.autoplay&&e.start(),e.calculateSlides(),e.$context.trigger(e._+".ready"),e.animate(e.options.index||e.current,"init")},e.setup=function(){e.$context.addClass(e.prefix+e.options.animation).wrap('
    '),e.$parent=e.$context.parent("."+e._);var t=e.$context.css("position");"static"===t&&e.$context.css("position","relative"),e.$context.css("overflow","hidden")},e.calculateSlides=function(){if(e.total=e.$slides.length,"fade"!==e.options.animation){var t="width";"vertical"===e.options.animation&&(t="height"),e.$container.css(t,100*e.total+"%").addClass(e.prefix+"carousel"),e.$slides.css(t,100/e.total+"%")}},e.start=function(){return e.interval=setTimeout(function(){e.next()},e.options.delay),e},e.stop=function(){return clearTimeout(e.interval),e},e.initNav=function(){var t=$('');e.$slides.each(function(n){var i=this.getAttribute("data-nav")||n+1;$.isFunction(e.options.nav)&&(i=e.options.nav.call(e.$slides.eq(n),n,i)),t.children("ol").append('
  • '+i+"
  • ")}),e.$nav=t.insertAfter(e.$context),e.$nav.find("li").on("click"+e.eventSuffix,function(){var t=$(this).addClass(e.options.activeClass);t.siblings().removeClass(e.options.activeClass),e.animate(t.attr("data-slide"))})},e.initArrows=function(){e.options.arrows===!0&&(e.options.arrows=e.defaults.arrows),$.each(e.options.arrows,function(t,n){e.$arrows.push($(n).insertAfter(e.$context).on("click"+e.eventSuffix,e[t]))})},e.initKeys=function(){e.options.keys===!0&&(e.options.keys=e.defaults.keys),$(document).on("keyup"+e.eventSuffix,function(t){$.each(e.options.keys,function(n,i){t.which===i&&$.isFunction(e[n])&&e[n].call(e)})})},e.initSwipe=function(){var t=e.$slides.width();e.$container.on({swipeleft:e.next,swiperight:e.prev,movestart:function(t){return t.distX>t.distY&&t.distX<-t.distY||t.distX-t.distY?!!t.preventDefault():void e.$container.css("position","relative")}}),"fade"!==e.options.animation&&e.$container.on({move:function(n){e.$container.css("left",-(100*e.current)+100*n.distX/t+"%")},moveend:function(n){return Math.abs(n.distX)/t<$.event.special.swipe.settings.threshold?e._move(e.$container,{left:-(100*e.current)+"%"},!1,200):void 0}})},e.initInfinite=function(){var t=["first","last"];t.forEach(function(n,i){e.$slides.push.apply(e.$slides,e.$slides.filter(':not(".'+e._+'-clone")')[n]().clone().addClass(e._+"-clone")["insert"+(0===i?"After":"Before")](e.$slides[t[~~!i]]()))}),e.$container.css({marginLeft:"-100%"})},e.destroyArrows=function(){e.$arrows.forEach(function(t){t.remove()})},e.destroySwipe=function(){e.$container.off("movestart move moveend")},e.destroyKeys=function(){$(document).off("keyup"+e.eventSuffix)},e.setIndex=function(t){return 0>t&&(t=e.total-1),e.current=Math.min(Math.max(0,t),e.total-1),e.options.nav&&e.$nav.find('[data-slide="'+e.current+'"]')._toggleActive(e.options.activeClass),e.$slides.eq(e.current)._toggleActive(e.options.activeClass),e},e.animate=function(t,n){if("first"===t&&(t=0),"last"===t&&(t=e.total),isNaN(t))return e;e.options.autoplay&&e.stop().start(),e.setIndex(t),e.$context.trigger(e._+".change",[t,e.$slides.eq(t)]);var i="animate"+$._ucfirst(e.options.animation);return $.isFunction(e[i])&&e[i](e.current,n),e},e.next=function(){var t=e.current+1;return t>=e.total&&(t=0),e.animate(t,"next")},e.prev=function(){return e.animate(e.current-1,"prev")},e.animateHorizontal=function(t){var n="left";return"rtl"===e.$context.attr("dir")&&(n="right"),e.slide(n,t)},e.animateVertical=function(t){return e.options.animateHeight=!0,e.slide("top",t)},e.slide=function(t,n){if(e.options.animateHeight&&e._move(e.$context,{height:e.$slides.eq(n).outerHeight()},!1),e.options.infinite){var i;n===e.total-1&&(i=e.total-3,n=-1),n===e.total-2&&(i=0,n=e.total-2),"number"==typeof i&&(e.setIndex(i),e.$context.on(e._+".moved",function(){e.current===i&&e.$container.css(t,-(100*i)+"%").off(e._+".moved")}))}var o={};return o[t]=-(100*n)+"%",e._move(e.$container,o)},e.animateFade=function(t){var n=e.$slides.eq(t).addClass(e.options.activeClass);e._move(n.siblings().removeClass(e.options.activeClass),{opacity:0}),e._move(n,{opacity:1},!1)},e._move=function(t,n,i,o){return i!==!1&&(i=function(){e.$context.trigger(e._+".moved")}),t._move(n,o||e.options.speed,e.options.easing,i)},e.init(n)},$.fn._toggleActive=function(t){return this.addClass(t).siblings().removeClass(t)},$._ucfirst=function(t){return(t+"").toLowerCase().replace(/^./,function(t){return t.toUpperCase()})},$.fn._move=function(){var t="animate";return this.stop(!0,!0),$.fn.velocity&&(t="velocity"),$.fn[t].apply(this,arguments)},void($.fn.unslider=function(t){return this.each(function(){var n=$(this);if("string"==typeof t&&n.data("unslider")){t=t.split(":");var e=t[0],i=n.data("unslider")[e];if(t[1]){var o=t[1].split(",");return $.isFunction(i)&&i.apply(n,o)}return $.isFunction(i)&&i(),this}return n.data("unslider",new $.Unslider(n,t))})})):console.warn("Unslider needs jQuery")}(window.jQuery); \ No newline at end of file diff --git a/src/css/unslider/reset.less b/src/css/unslider/reset.less index d6e6bb1..7daeb42 100644 --- a/src/css/unslider/reset.less +++ b/src/css/unslider/reset.less @@ -13,6 +13,20 @@ } } + // Vertical sliders don't float left + &-vertical { + > ul { + height: 100%; + } + + li { + float: none; + width: 100%; + } + } + + // Fading needs everything to appear on top of + // each other &-fade { position: relative; diff --git a/src/js/unslider.js b/src/js/unslider.js index 415cae4..46b6cd1 100755 --- a/src/js/unslider.js +++ b/src/js/unslider.js @@ -155,7 +155,7 @@ self.setup = function() { // Add a CSS hook to the main element - self.$context.addClass(self.prefix + 'slider ' + self.prefix + self.options.animation).wrap('
    '); + self.$context.addClass(self.prefix + self.options.animation).wrap('
    '); self.$parent = self.$context.parent('.' + self._); // We need to manually check if the container is absolutely @@ -178,8 +178,14 @@ // Set the total width if(self.options.animation !== 'fade') { - self.$container.css('width', (self.total * 100) + '%').addClass(self.prefix + 'carousel'); - self.$slides.css('width', (100 / self.total) + '%'); + var prop = 'width'; + + if(self.options.animation === 'vertical') { + prop = 'height'; + } + + self.$container.css(prop, (self.total * 100) + '%').addClass(self.prefix + 'carousel'); + self.$slides.css(prop, (100 / self.total) + '%'); } }; @@ -190,8 +196,10 @@ // Move on to the next slide self.next(); - // And restart our timeout - self.start(); + // If we've got autoplay set up + // we don't need to keep starting + // the slider from within our timeout + // as .animate() calls it for us }, self.options.delay); return self; @@ -326,10 +334,10 @@ // Exclude all cloned slides and call .first() or .last() // depending on what `item` is. - self.$slides.filter(':not(".' + self._ + '-cloned")')[item]() + self.$slides.filter(':not(".' + self._ + '-clone")')[item]() // Make a copy of it and identify it as a clone - .clone().addClass(self._ + '-cloned') + .clone().addClass(self._ + '-clone') // Either insert before or after depending on whether we're // the first or last clone @@ -342,7 +350,7 @@ }); // So then we need to hide the first slide - self.$container.css('margin-left', '-100%'); + self.$container.css({marginLeft: '-100%'}); }; // Remove any trace of arrows @@ -357,10 +365,7 @@ // Remove any swipe events and reset the position self.destroySwipe = function() { // We bind to 4 events, so we'll unbind those - self.$container.off('movestart swipeleft move moveend') - // If this was called mid-swipe we need to reset - // the swipe position as well. Can do that here. - .css('left', 0); + self.$container.off('movestart move moveend'); }; // Unset the keyboard navigation @@ -450,10 +455,39 @@ // Our default animation method, the old-school left-to-right // horizontal animation self.animateHorizontal = function(to) { + var prop = 'left'; + + // Add RTL support, slide the slider + // the other way if the site is right-to-left + if(self.$context.attr('dir') === 'rtl') { + prop = 'right'; + } + + return self.slide(prop, to); + }; + + // The same animation methods, but vertical support + // RTL doesn't affect the vertical direction so we + // can just call as is + self.animateVertical = function(to) { + self.options.animateHeight = true; + return self.slide('top', to); + } + + // Actually move the slide now + // We have to pass a property to animate as there's + // a few different directions it can now move, but it's + // otherwise unchanged from before. + self.slide = function(prop, to) { + // If we want to change the height of the slider + // to match the current slide, you can set + // {animateHeight: true} if(self.options.animateHeight) { - self._move(self.$context, {height: self.$slides.eq(to).height()}, false); + self._move(self.$context, {height: self.$slides.eq(to).outerHeight()}, false); } + // For infinite sliding we add a dummy slide at the end and start + // of each slider to give the appearance of being infinite if(self.options.infinite) { var dummy; @@ -482,13 +516,21 @@ // this whole mess up. self.$context.on(self._ + '.moved', function() { if(self.current === dummy) { - self.$container.css('left', -(100 * dummy) + '%').off(self._ + '.moved'); + self.$container.css(prop, -(100 * dummy) + '%').off(self._ + '.moved'); } }); } } - return self._move(self.$container, {left: -(100 * to) + '%'}); + // We need to create an object to store our property in + // since we don't know what it'll be. + var obj = {}; + + // Manually create it here + obj[prop] = -(100 * to) + '%'; + + // And animate using our newly-created object + return self._move(self.$container, obj); }; @@ -528,20 +570,22 @@ // Simples. $._ucfirst = function(str) { // Take our variable, run a regex on the first letter - return str.toString().toLowerCase().replace(/^./, function(match) { + return (str + '').toLowerCase().replace(/^./, function(match) { // And uppercase it. Simples. return match.toUpperCase(); }); }; $.fn._move = function() { + var type = 'animate'; + this.stop(true, true); if($.fn.velocity) { - return $.fn.velocity.apply(this, arguments); + type = 'velocity'; } - return $.fn.animate.apply(this, arguments); + return $.fn[type].apply(this, arguments); }; // And set up our jQuery plugin