From db9d1fb7874e4a55166eda5bb535139c5fdea98b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Cha=C5=82ubek?= Date: Sat, 6 Aug 2016 15:33:34 +0200 Subject: [PATCH] Stop sliding when only having 1 image? #158 --- dist/css/glide.theme.css | 16 +++----- dist/css/glide.theme.min.css | 2 +- dist/glide.js | 74 +++++++++++++++++++++++++++++++----- dist/glide.min.js | 2 +- dist/glide.min.js.map | 2 +- examples/basic.html | 2 +- src/Glide.js | 4 +- src/less/glide.theme.less | 22 ++++------- src/modules/Animation.js | 6 +++ src/modules/Api.js | 1 + src/modules/Arrows.js | 17 ++++++++- src/modules/Run.js | 27 +++++++++++++ src/sass/glide.theme.scss | 22 ++++------- tests/fixtures/single.html | 18 +++++++++ tests/specs/RunSpec.js | 65 +++++++++++++++++++++++++++++++ 15 files changed, 224 insertions(+), 56 deletions(-) create mode 100755 tests/fixtures/single.html create mode 100755 tests/specs/RunSpec.js diff --git a/dist/css/glide.theme.css b/dist/css/glide.theme.css index 52e0ca6c..5b26aba7 100644 --- a/dist/css/glide.theme.css +++ b/dist/css/glide.theme.css @@ -21,8 +21,12 @@ background-color: transparent; border: 2px solid rgba(255, 255, 255, 0.5); border-radius: 4px; - -webkit-transition: border 300ms ease-in-out; - transition: border 300ms ease-in-out; + opacity: 1; + -webkit-transition: opacity 150ms ease, border 300ms ease-in-out; + transition: opacity 150ms ease, border 300ms ease-in-out; +} +.glide__arrow.disabled { + opacity: 0.33; } .glide__arrow:focus { outline: none; @@ -102,11 +106,3 @@ border: 2px solid white; background-color: rgba(255, 255, 255, 0.5); } -.glide--slider .glide__arrow { - opacity: 1; - -webkit-transition: opacity 150ms ease; - transition: opacity 150ms ease; -} -.glide--slider .glide__arrow.disabled { - opacity: 0.33; -} diff --git a/dist/css/glide.theme.min.css b/dist/css/glide.theme.min.css index 2bfaafd6..25941570 100644 --- a/dist/css/glide.theme.min.css +++ b/dist/css/glide.theme.min.css @@ -1 +1 @@ -.glide__arrows{position:absolute}.glide--horizontal .glide__arrows{top:50%;width:92%;margin-left:4%}.glide--vertical .glide__arrows{left:50%;height:88%;margin-top:6%}.glide__arrow{position:absolute;z-index:2;color:white;text-transform:uppercase;font:11px Arial,sans-serif;padding:9px 12px;background-color:transparent;border:2px solid rgba(255,255,255,0.5);border-radius:4px;-webkit-transition:border 300ms ease-in-out;transition:border 300ms ease-in-out}.glide__arrow:focus{outline:none}.glide__arrow:hover{border-color:white}.glide--horizontal .glide__arrow{-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%)}.glide--horizontal .glide__arrow.prev{left:0}.glide--horizontal .glide__arrow.next{right:0}.glide--vertical .glide__arrow{-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%)}.glide--vertical .glide__arrow.prev{top:0}.glide--vertical .glide__arrow.next{bottom:0}.glide__bullets{position:absolute;z-index:2;list-style:none}.glide--horizontal .glide__bullets{bottom:8%;left:0;width:100%;height:12px;text-align:center}.glide--vertical .glide__bullets{top:50%;right:8%;width:12px;height:auto;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%)}.glide__bullets>*{display:inline-block;background-color:rgba(255,255,255,0.5);width:12px;height:12px;padding:0;cursor:pointer;border-radius:50%;border:2px solid transparent;-webkit-transition:all 300ms ease-in-out;transition:all 300ms ease-in-out}.glide--horizontal .glide__bullets>*{margin:0 5px}.glide--vertical .glide__bullets>*{vertical-align:middle}.glide__bullets>*.active{background-color:white}.glide__bullets>*:focus{outline:none}.glide__bullets>*:hover,.glide__bullets>*:focus{border:2px solid white;background-color:rgba(255,255,255,0.5)}.glide--slider .glide__arrow{opacity:1;-webkit-transition:opacity 150ms ease;transition:opacity 150ms ease}.glide--slider .glide__arrow.disabled{opacity:.33} \ No newline at end of file +.glide__arrows{position:absolute}.glide--horizontal .glide__arrows{top:50%;width:92%;margin-left:4%}.glide--vertical .glide__arrows{left:50%;height:88%;margin-top:6%}.glide__arrow{position:absolute;z-index:2;color:white;text-transform:uppercase;font:11px Arial,sans-serif;padding:9px 12px;background-color:transparent;border:2px solid rgba(255,255,255,0.5);border-radius:4px;opacity:1;-webkit-transition:opacity 150ms ease,border 300ms ease-in-out;transition:opacity 150ms ease,border 300ms ease-in-out}.glide__arrow.disabled{opacity:.33}.glide__arrow:focus{outline:none}.glide__arrow:hover{border-color:white}.glide--horizontal .glide__arrow{-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%)}.glide--horizontal .glide__arrow.prev{left:0}.glide--horizontal .glide__arrow.next{right:0}.glide--vertical .glide__arrow{-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%)}.glide--vertical .glide__arrow.prev{top:0}.glide--vertical .glide__arrow.next{bottom:0}.glide__bullets{position:absolute;z-index:2;list-style:none}.glide--horizontal .glide__bullets{bottom:8%;left:0;width:100%;height:12px;text-align:center}.glide--vertical .glide__bullets{top:50%;right:8%;width:12px;height:auto;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%)}.glide__bullets>*{display:inline-block;background-color:rgba(255,255,255,0.5);width:12px;height:12px;padding:0;cursor:pointer;border-radius:50%;border:2px solid transparent;-webkit-transition:all 300ms ease-in-out;transition:all 300ms ease-in-out}.glide--horizontal .glide__bullets>*{margin:0 5px}.glide--vertical .glide__bullets>*{vertical-align:middle}.glide__bullets>*.active{background-color:white}.glide__bullets>*:focus{outline:none}.glide__bullets>*:hover,.glide__bullets>*:focus{border:2px solid white;background-color:rgba(255,255,255,0.5)} \ No newline at end of file diff --git a/dist/glide.js b/dist/glide.js index 9184d4b6..c3387a44 100644 --- a/dist/glide.js +++ b/dist/glide.js @@ -28,6 +28,7 @@ var Animation = function(Glide, Core) { * Animation constructor. */ function Animation() { + } /** @@ -37,6 +38,11 @@ var Animation = function(Glide, Core) { * @return {self} */ Animation.prototype.make = function(displacement) { + // Do not run if we have only one slide. + if (! Core.Run.canProcess()) { + return Core.Arrows.disable(); + } + // Parse displacement to integer before use. offset = (typeof displacement !== 'undefined') ? parseInt(displacement) : 0; @@ -226,6 +232,7 @@ var Api = function(Glide, Core) { * Api constructor. */ function Api() { + } /** @@ -356,6 +363,8 @@ var Api = function(Glide, Core) { Core.Arrows.unbind(); Core.Bullets.unbind(); + Glide.destroyed = true; + delete Glide.slider; delete Glide.track; delete Glide.slides; @@ -421,7 +430,7 @@ var Arrows = function(Glide, Core) { /** - * Disable next/previous arrow. + * Disable next/previous arrow and enable another. * * @param {String} type * @return {Void} @@ -429,6 +438,10 @@ var Arrows = function(Glide, Core) { Arrows.prototype.disable = function(type) { var classes = Glide.options.classes; + if (!type) { + return this.disableBoth(); + } + this.items.filter('.' + classes['arrow' + Core.Helper.capitalise(type)]) .unbind('click.glide touchstart.glide') .addClass(classes.disabled) @@ -439,6 +452,17 @@ var Arrows = function(Glide, Core) { .removeClass(classes.disabled); }; + /** + * Disable both arrows. + * + * @return {Void} + */ + Arrows.prototype.disableBoth = function() { + this.items + .unbind('click.glide touchstart.glide') + .addClass(Glide.options.classes.disabled); + }; + /** * Show both arrows. @@ -1049,12 +1073,14 @@ var Events = function(Glide, Core) { Events.prototype.resize = function() { $(window).on('resize.glide.' + Glide.uuid, Core.Helper.throttle(function() { - Core.Transition.jumping = true; - Glide.setup(); - Core.Build.init(); - Core.Run.make('=' + Glide.current, false); - Core.Run.play(); - Core.Transition.jumping = false; + if(!Glide.destroyed) { + Core.Transition.jumping = true; + Glide.setup(); + Core.Build.init(); + Core.Run.make('=' + Glide.current, false); + Core.Run.play(); + Core.Transition.jumping = false; + } }, Glide.options.throttle)); }; @@ -1421,6 +1447,10 @@ var Run = function(Glide, Core) { var that = this; + if (! this.canProcess()) { + return; + } + if (Glide.options.autoplay || this.running) { if (typeof this.interval === 'undefined') { @@ -1508,6 +1538,11 @@ var Run = function(Glide, Core) { // Extract move steps. this.steps = (move.substr(1)) ? move.substr(1) : 0; + // Do not run if we have only one slide. + if (! this.canProcess()) { + return this.stop(); + } + // Stop autoplay until hoverpause is not set. if (!Glide.options.hoverpause) { this.pause(); @@ -1600,6 +1635,24 @@ var Run = function(Glide, Core) { }; + /** + * Stop slider from running. + * + * @return {void} + */ + Run.prototype.stop = function() { + this.pause(); + }; + + /** + * Stop slider from running. + * + * @return {void} + */ + Run.prototype.canProcess = function() { + return Glide.slides.length > 1; + }; + // Return class. return new Run(); @@ -2043,6 +2096,9 @@ var Glide = function(element, options) { this.collect(); this.setup(); + // Mark the glide as not destroyed + this.destroyed = false; + // Call before init callback. this.options.beforeInit({ index: this.current, @@ -2060,11 +2116,11 @@ var Glide = function(element, options) { Helper: Helper, Translate: Translate, Transition: Transition, + Arrows: Arrows, + Bullets: Bullets, Run: Run, Animation: Animation, Clones: Clones, - Arrows: Arrows, - Bullets: Bullets, Height: Height, Build: Build, Events: Events, diff --git a/dist/glide.min.js b/dist/glide.min.js index 734dbddd..45df9a80 100644 --- a/dist/glide.min.js +++ b/dist/glide.min.js @@ -7,5 +7,5 @@ * Licensed under the MIT license */ -!function(a,b,c,d){var e=function(a,b){function c(){}var d;return c.prototype.make=function(b){return d="undefined"!=typeof b?parseInt(b):0,this[a.options.type](),this},c.prototype.after=function(b){return setTimeout(function(){b()},a.options.animationDuration+20)},c.prototype.slider=function(){var c=a[a.size]*(a.current-1),e=b.Clones.shift-a.paddings;b.Run.isStart()?(e=a.options.centered?Math.abs(e):0,b.Arrows.disable("prev")):b.Run.isEnd()?(e=Math.abs(a.options.centered?e:2*e),b.Arrows.disable("next")):(e=Math.abs(e),b.Arrows.enable()),a.track.css({transition:b.Transition.get("all"),transform:b.Translate.set(a.axis,c-e-d)})},c.prototype.carousel=function(){var c,e=a[a.size]*a.current;c=a.options.centered?b.Clones.shift-a.paddings:b.Clones.shift,b.Run.isOffset("<")&&(e=0,b.Run.flag=!1,this.after(function(){a.track.css({transition:b.Transition.clear("all"),transform:b.Translate.set(a.axis,a[a.size]*a.length+c)})})),b.Run.isOffset(">")&&(e=a[a.size]*a.length+a[a.size],b.Run.flag=!1,this.after(function(){a.track.css({transition:b.Transition.clear("all"),transform:b.Translate.set(a.axis,a[a.size]+c)})})),a.track.css({transition:b.Transition.get("all"),transform:b.Translate.set(a.axis,e+c-d)})},c.prototype.slideshow=function(){a.slides.css("transition",b.Transition.get("opacity")).eq(a.current-1).css("opacity",1).siblings().css("opacity",0)},new c},f=function(a,b){function c(){}return c.prototype.instance=function(){return{current:function(){return a.current},go:function(a,c){b.Run.pause(),b.Run.make(a,c),b.Run.play()},jump:function(a,c){b.Transition.jumping=!0,b.Animation.after(function(){b.Transition.jumping=!1}),b.Run.make(a,c)},move:function(a){b.Transition.jumping=!0,b.Animation.make(a),b.Transition.jumping=!1},start:function(c){b.Run.running=!0,a.options.autoplay=parseInt(c),b.Run.play()},play:function(){return b.Run.play()},pause:function(){return b.Run.pause()},destroy:function(){b.Run.pause(),b.Clones.remove(),b.Helper.removeStyles([a.track,a.slides]),b.Bullets.remove(),a.slider.removeData("glide_api"),b.Events.unbind(),b.Touch.unbind(),b.Arrows.unbind(),b.Bullets.unbind(),delete a.slider,delete a.track,delete a.slides,delete a.width,delete a.length},refresh:function(){b.Run.pause(),a.collect(),a.setup(),b.Clones.remove().init(),b.Bullets.remove().init(),b.Build.init(),b.Run.make("="+parseInt(a.options.startAt),b.Run.play())}}},new c},g=function(b,c){function d(){this.build(),this.bind()}return d.prototype.build=function(){this.wrapper=b.slider.find("."+b.options.classes.arrows),this.items=this.wrapper.children()},d.prototype.disable=function(a){var d=b.options.classes;this.items.filter("."+d["arrow"+c.Helper.capitalise(a)]).unbind("click.glide touchstart.glide").addClass(d.disabled).siblings().bind("click.glide touchstart.glide",this.click).bind("mouseenter.glide",this.hover).bind("mouseleave.glide",this.hover).removeClass(d.disabled)},d.prototype.enable=function(){this.bind(),this.items.removeClass(b.options.classes.disabled)},d.prototype.click=function(b){b.preventDefault(),c.Events.disabled||(c.Run.pause(),c.Run.make(a(this).data("glide-dir")),c.Animation.after(function(){c.Run.play()}))},d.prototype.hover=function(a){if(!c.Events.disabled)switch(a.type){case"mouseleave":c.Run.play();break;case"mouseenter":c.Run.pause()}},d.prototype.bind=function(){this.items.on("click.glide touchstart.glide",this.click).on("mouseenter.glide",this.hover).on("mouseleave.glide",this.hover)},d.prototype.unbind=function(){this.items.off("click.glide touchstart.glide").off("mouseenter.glide").off("mouseleave.glide")},new d},h=function(a,b){function c(){this.init()}return c.prototype.init=function(){this[a.options.type](),this.active(),b.Height.set()},c.prototype.isType=function(b){return a.options.type===b},c.prototype.isMode=function(b){return a.options.mode===b},c.prototype.slider=function(){b.Transition.jumping=!0,a.slides[a.size](a[a.size]),a.track.css(a.size,a[a.size]*a.length),this.isMode("vertical")&&b.Height.set(!0),b.Animation.make(),b.Transition.jumping=!1},c.prototype.carousel=function(){b.Transition.jumping=!0,b.Clones.shift=a[a.size]*b.Clones.items.length/2-a[a.size],a.slides[a.size](a[a.size]),a.track.css(a.size,a[a.size]*a.length+b.Clones.getGrowth()),this.isMode("vertical")&&b.Height.set(!0),b.Animation.make(),b.Clones.append(),b.Transition.jumping=!1},c.prototype.slideshow=function(){b.Transition.jumping=!0,b.Animation.make(),b.Transition.jumping=!1},c.prototype.active=function(){a.slides.eq(a.current-1).addClass(a.options.classes.active).siblings().removeClass(a.options.classes.active)},new c},i=function(b,c){function d(){this.init(),this.bind()}return d.prototype.init=function(){return this.build(),this.active(),this},d.prototype.build=function(){this.wrapper=b.slider.children("."+b.options.classes.bullets);for(var c=1;c<=b.length;c++)a(" + + + +
+ +
+ +
+ + + + diff --git a/tests/specs/RunSpec.js b/tests/specs/RunSpec.js new file mode 100755 index 00000000..3c204efa --- /dev/null +++ b/tests/specs/RunSpec.js @@ -0,0 +1,65 @@ +jasmine.getFixtures().fixturesPath = '../tests/fixtures'; +jasmine.getStyleFixtures().fixturesPath = '../dist/css'; + +describe("Run", function() { + + var data; + var fixtures; + var slider; + var wrapper; + var track; + var slides; + var arrows; + var arrowsWrapper; + var bullets; + var bulletsWrapper; + var api; + + beforeEach(function () { + + loadFixtures('single.html'); + loadStyleFixtures('glide.core.css'); + loadStyleFixtures('glide.theme.css'); + + data = getJSONFixture('data.json'); + fixtures = loadJSONFixtures('data.json'); + data = fixtures['data.json']; + + slider = $(data.base); + wrapper = slider.find(data.wrapper); + track = wrapper.find(data.track); + slides = track.children(); + arrowsWrapper = slider.find(data.arrows); + arrows = arrowsWrapper.children(); + bulletsWrapper = slider.find(data.bullets); + bullets = bulletsWrapper.children(); + + options = { + animationDuration: 10 + }; + + api = slider.glide(options).data('glide_api'); + + }); + + it("Glide should not slide if there is only one slide", function(done) { + api.go('>'); + + setTimeout(function(){ + var current = slides.index($(data.active)) + 1; + + expect(current).toBe(1); + + done(); + }, options.animationDuration*10); + }); + + it("If there is only one slide arrows should be disabled", function() { + var next = arrows.filter(data.arrowNext); + var prev = arrows.filter(data.arrowPrev); + + expect(next.hasClass('disabled')).toBe(true); + expect(prev.hasClass('disabled')).toBe(true); + }); + +});