Disable Swiper Slider if only 1 slide
Asked Answered
H

16

21

I'm using swiper slider on a site and would like to have it disabled if there is only one slide.

Currently with only one slide the pagination appears and you can click that or swipe. Ideally there shouldn't be any interaction if there is only one slide.

My current js is:

  var swiper = new Swiper('.swiper-container', {
    // Optional parameters
    direction: 'horizontal',
    loop: false,
    //autoplay: 6500,
    autoplayDisableOnInteraction: false,

    keyboardControl: true,
    mousewheelControl: true,

    pagination: '.swiper-pagination',
    paginationClickable: true,

  });
Hoyle answered 21/10, 2016 at 20:57 Comment(0)
H
16

I was looking for a way to do so too, but since I didn't find any “official” way to disable the swipe and hide the pagers, I decided to improvise a bit.

So in your script, you can add this after your Swiper variable:

JS:

if($(".slider .slide").length == 1) {
    $('.swiper-wrapper').addClass( "disabled" );
    $('.swiper-pagination').addClass( "disabled" );
}

This will add the class disabled to your wrapper and your pagination if there is only one slide in your slider. You can now add some CSS to bypass the Swiper effexts:

CSS:

.swiper-wrapper.disabled {
    transform: translate3d(0px, 0, 0) !important;
}
.swiper-pagination.disabled {
    display: none;
}

Note that this will only work when the loop is set to false (like in your case). If the loop is active, Swiper will add slide duplicates before and after your only slide, making a total of 3 identicals slides. You can then change the length == 1 to length == 3.

Hope this will help!

Hadlee answered 2/11, 2016 at 20:51 Comment(4)
better wrap everything like: if($(".slider .slide").length == 1) { var swiper = new Swiper('.swiper-container'); }Demott
thanks a ton for this! I've been searching for an easy way to disable the slider for larger screens. Set a media query, add transform: translate3d(0px, 0, 0) !important; and BAMSurfactant
What about the cloned slides it puts in? There's technically only one slide but the length comes back as 3. Suppose I could test for that though it seems ripe for errorsFungiform
This would be ok if you'd have one slide per view. Imagine having more than one slides visible and making this responsive.Joke
A
55

There is an option in Swiper API that might be useful :

watchOverflow (boolean|false)
// When enabled Swiper will be disabled and hide navigation buttons on case there are not enough slides for sliding
Apriorism answered 26/3, 2018 at 8:6 Comment(3)
Thanks a million. Very clean solution to disable swiping. Used it together with zoom {zoom : true, watchOverflow: true} to display a picture that can be zoomed but not swiped. Moving around the picture while zoomed in still works.Somatotype
This is the best solutionLactoprotein
This option does not work when effect is set to fade .Joke
H
16

I was looking for a way to do so too, but since I didn't find any “official” way to disable the swipe and hide the pagers, I decided to improvise a bit.

So in your script, you can add this after your Swiper variable:

JS:

if($(".slider .slide").length == 1) {
    $('.swiper-wrapper').addClass( "disabled" );
    $('.swiper-pagination').addClass( "disabled" );
}

This will add the class disabled to your wrapper and your pagination if there is only one slide in your slider. You can now add some CSS to bypass the Swiper effexts:

CSS:

.swiper-wrapper.disabled {
    transform: translate3d(0px, 0, 0) !important;
}
.swiper-pagination.disabled {
    display: none;
}

Note that this will only work when the loop is set to false (like in your case). If the loop is active, Swiper will add slide duplicates before and after your only slide, making a total of 3 identicals slides. You can then change the length == 1 to length == 3.

Hope this will help!

Hadlee answered 2/11, 2016 at 20:51 Comment(4)
better wrap everything like: if($(".slider .slide").length == 1) { var swiper = new Swiper('.swiper-container'); }Demott
thanks a ton for this! I've been searching for an easy way to disable the slider for larger screens. Set a media query, add transform: translate3d(0px, 0, 0) !important; and BAMSurfactant
What about the cloned slides it puts in? There's technically only one slide but the length comes back as 3. Suppose I could test for that though it seems ripe for errorsFungiform
This would be ok if you'd have one slide per view. Imagine having more than one slides visible and making this responsive.Joke
T
6

One of the options would be to conditionally add options, as below:

    let options = {};

    if ( $(".swiper-container .swiper-slide").length == 1 ) {
        options = {
            direction: 'horizontal',
            loop: false,
            autoplayDisableOnInteraction: false,

            keyboardControl: true,
            mousewheelControl: true,

            pagination: '.swiper-pagination',
            paginationClickable: true,
        }
    } else {
        options = {
            loop: false,
            autoplay: false,
        }
    }

    var swiper = new Swiper('.swiper-container', options);
Tyrant answered 2/11, 2017 at 15:13 Comment(0)
N
5

Simply add a condition:

if ($('.swiper-container .swiper-slide').length > 1) {
  var swiper = new Swiper('.swiper-container', {
    // Optional parameters
    direction: 'horizontal',
    loop: false,
    //autoplay: 6500,
    autoplayDisableOnInteraction: false,

    keyboardControl: true,
    mousewheelControl: true,

    pagination: '.swiper-pagination',
    paginationClickable: true,

  });
}
Nordau answered 24/3, 2017 at 12:15 Comment(1)
Thanks, I found this solution to be pretty simple. I also hid the nav buttons through CSS, by default, and added a class to the swiper container that triggers the nav buttons to display.Headphone
R
5

Just check how many slides you got:

const numberOfSlides = document.querySelectorAll('.swiper-slide').length;

Then set allowSlidePrev/allowSlideNext (or whatever you want to prevent) to false if it's only one slide:

const slider = new Swiper('.swiper-container', {

    allowSlidePrev:numberOfSlides === 1 ? false:true,
    allowSlideNext:numberOfSlides === 1 ? false:true

});

You also have access to the collection of slides so you could also turn on/off these things in your events. In init for example:

on: {
    init: function () {
        const numberOfSlides = this.slides.length;
        ...
    }
}
Robinrobina answered 28/9, 2019 at 16:9 Comment(0)
O
3

Since some of the provided solutions seem outdated or conflict with certain combinations of autoplay or loop-settings, this one here takes care of that, keeping everything inside the initialization call:

const heroSlider = new Swiper('#hero-slider .swiper', {
  loop: true,
  watchOverflow: true,
  autoplay: {
    delay: 4000,
  },
  speed: 500,
  navigation: {
    nextEl: '#hero-slider .swiper-button-next',
    prevEl: '#hero-slider .swiper-button-prev',
  },
  on: {
    beforeInit() {
      const slides = this.el.querySelectorAll('.swiper-slide');

      if (slides) {
        this.params.loop = slides.length > 1;
        this.params.autoplay.enabled = slides.length > 1;
      }
    },
  },
});

The above shows no navigation-controls and disables autoloop if we got just 1 slide, effectively disabling the swiper - otherwise controls are shown and autoloop starts as usual. We count the slides here using a bypass over the DOM instead via the Swiper-API, since the latter isn't reliable at this point - nor is it on init (with a single slide f.i., this.slides.length delivers 0 on beforeInit (no surprise) and 3 onInit, since the initial default setting of loop: true seems to produce slide-duplicates when we got just 1 slide etc.).

Long story short: Works for me!

Overmantel answered 27/2, 2023 at 10:50 Comment(2)
As for today, this is the only correct solution, +1 to have it wriiten in JavaScript and not jQueryWalkthrough
yes this works must be accepted as solutionSadomasochism
F
2

Based on document:

swiper.allowTouchMove = false; 
Footfall answered 11/3, 2021 at 11:7 Comment(2)
Please add a short explanation about your solution.Rawls
This is the only one that worked for me. Not sure why it was voted down. swiperjs.com/swiper-api#parametersAle
T
1

Laconic solution:

var swiper = new Swiper('.swiper-container', {
    navigation: {
        prevEl: '.swiper-button-prev',
        nextEl: '.swiper-button-next',
    },
    on: {
        init: function () {
            if (this.slides.length <= 1) {
                // First way:
                this.allowSlidePrev = this.allowSlideNext = false; // disabling swiping
                this.el.querySelector(".swiper-button-prev").setAttribute('hidden', '');  // hiding arrows prev&next
                this.el.querySelector(".swiper-button-next").setAttribute('hidden', '');

                // Second way:
                // this.el.classList.add('swiper-no-swiping');
            }
        }
    }
});
Trimble answered 20/3, 2021 at 16:10 Comment(0)
M
0

I propose to use update swiper function with new options like this:

params.loop = false;
params.pagination = null;
swiper.update();

Params is the object which was used with swiper initialization.

Thanks!

Measureless answered 1/3, 2018 at 10:6 Comment(0)
C
0

You can check the number of slides, and add swiper-no-swiping class to disable swiping. This assumes noSwiping is kept as true (default setting) [docs]

  // 1. Initialize Swiper
  var swiper = new Swiper('.swiper-container', {
    // Sample parameters
    direction: 'horizontal',
    loop: false,
    autoplayDisableOnInteraction: false,
    keyboardControl: true,
    mousewheelControl: true,
    pagination: '.swiper-pagination',
    paginationClickable: true,
  });


  swiper.on('init', function() {
     // 2. Get Slide count
     if (slider.slides.length <= 1) {
        // 3. Add swiper-no-swiping class
        document.querySelector('.swiper-container').classList.add('swiper-no-swiping')
     }
  });
Cash answered 10/5, 2020 at 14:26 Comment(0)
F
0

CSS class name added to navigation button when it becomes disabled

 disabledClass: 'disabled_swiper_button'

for reference click https://swiperjs.com/swiper-api#navigation

Footfall answered 31/3, 2021 at 6:36 Comment(0)
S
0

With the latest swiper.js version, you can add enabled: false to the options. this will, when disabled hide all navigation elements and won't respond to any events and interactions

Found on the API documentation documentation.

Tested with v6.6.1

Here an example

var items = ['slide1']

var options = {
 enabled: items.length > 1
}
Sanctity answered 18/5, 2021 at 9:49 Comment(0)
N
0
  1. You can do it through parameter https://swiperjs.com/swiper-api#param-watchOverflow:
watchOverflow (boolean|false)

// When enabled Swiper will be disabled and hide navigation buttons on case there are not enough slides for sliding
  1. Another way, with method https://swiperjs.com/swiper-api#method-swiper-disable:
// detect sliders
if (swiper.slides.length === 1) {

    // Disable Swiper (if it was enabled). When Swiper is disabled, it will hide all navigation elements and won't respond to any events and interactions
    swiper.disable();
}
Nari answered 5/7, 2022 at 6:55 Comment(0)
U
0
    on: {
        slideChange: function () {
            if (this.slides.length === 1) {
                this.allowSlidePrev = false;
                this.allowSlideNext = false;
            } else {
                this.allowSlidePrev = true;
                this.allowSlideNext = true;
            }
        }
    }
Ungley answered 22/2 at 16:41 Comment(0)
H
0

I used init because it didn't work with beforeInit.

Very useful because otherwise we don't know exactly how to modify options : You can view all options and their structure with console.log(this.params);

Here is an example :

    var swiper2 = new Swiper(".slider-large", {
              spaceBetween: 30,
              pagination: {
                el: '.swiper-pagination',
                clickable: true,
              },
              keyboard: {
                enabled: true,
              },
              thumbs: {
                swiper: swiper,
              },
              loop: false,
              lazy: true,
              watchOverflow: true,
              on: {
                init() {
                  // check number of slides
                  const slides_length = this.slides.length;
                  // check parameters before change
                  console.log(this.params);
                  if (slides_length === 1) {
                    // examples, do what what you want, some examples
                    this.params.allowTouchMove = false;
                    this.params.keyboard.enabled = false;
                    this.params.watchOverflow = false;
                    this.params.enabled = false;
                  }
                  // check if parameters has been modified
                  console.log(this.params);
                },
                // not asked : if you want to know the current index
                slideChange: function () {
                  swiper2activeIndex = this.activeIndex; // get current slide's index
                  console.log(swiper2activeIndex);
    
                },
              }
            });
Halfsole answered 16/4 at 18:4 Comment(0)
F
-2

Well using $ionicSlides for me works fine to ask the length of the array and if is one or less get the Swiper instance and call these functions:

 $scope.$on("$ionicSlides.sliderInitialized", function (event, data) { 
    $scope.slider2 = data.slider;
      $scope.slider2.activeIndex = 0;

     if (vm.slidetext && vm.slidetext.length <= 1) {

        $scope.slider2.destroyLoop();
        $scope.slider2.stopAutoplay();
        $scope.slider2.lockSwipes();
      } 
}

But these functions are for the native Swiper so should works fine

Fizz answered 28/11, 2018 at 8:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.