")}),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