swiper: Solution: Last slide not getting active when 'slidePerView' set to 'auto'.

I currently experienced the same problems like as many people did and also looked through the issues but no results. https://github.com/nolimits4web/swiper/issues/2571, https://github.com/nolimits4web/swiper/issues/1257, https://github.com/nolimits4web/swiper/issues/534 Finally, I found out a way to do it, a better way to do it guys!.

By setting the snapGrid settings as same as the slidesGrid settings after the swiper initialized. And then the swiper will work as what you expected.

const swiper = new Swiper(
    '.awesome-swiper', 
    {
        init: false,
        direction: 'horizontal',
        speed: 700,
        slidesPerView: 'auto',
        spaceBetween: 80,
    }
);

swiper.init();
swiper.snapGrid[swiper.snapGrid.length - 1] = swiper.slidesGrid[swiper.slidesGrid.length - 1];

or even completely replacing it by cloning the settings.

// can do this way
swiper.snapGrid = swiper.slidesGrid.slice(0);

// or ES6 way
swiper.snapGrid = [...swiper.slidesGrid];

Update: 2020-11-18

You will need to update the snapGrid when responsive by using built-in Events.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 15
  • Comments: 16

Commits related to this issue

Most upvoted comments

on: {
	snapGridLengthChange:function(){
		if( this.snapGrid.length != this.slidesGrid.length ){
			this.snapGrid = this.slidesGrid.slice(0);
		}
	}
}

I currently experienced the same problems like as many people did and also looked through the issues but no results. #2571, #1257, #534 Finally, I found out a way to do it, a better way to do it guys!.

By setting the snapGrid settings as same as the slidesGrid settings after the swiper initialized. And then the swiper will work as what you expected.

const swiper = new Swiper(
    '.awesome-swiper', 
    {
        init: false,
        direction: 'horizontal',
        speed: 700,
        slidesPerView: 'auto',
        spaceBetween: 80,
    }
);

swiper.init();
swiper.snapGrid[swiper.snapGrid.length - 1] = swiper.slidesGrid[swiper.slidesGrid.length - 1];

or even completely replacing it by cloning the settings.

// can do this way
swiper.snapGrid = swiper.slidesGrid.slice(0);

// or ES6 way
swiper.snapGrid = [...swiper.slidesGrid];

this work for me, but with a little adjustment: I placed this line this.snapGrid = [...this.slidesGrid]; inside of the reachEnd swiper event, like this:

const swiper = new Swiper('.awesome-swiper', {
    direction: 'horizontal',
    speed: 700,
    slidesPerView: 'auto',
    spaceBetween: 80,
    on: {
      reachEnd: function() {
        this.snapGrid = [...this.slidesGrid];
      },
    }
}

Any update on this, I’m dealing with the same issue where the slideChange event doesn’t get fired for the last slide when slidePerView is set to auto? I’m don’t think my issue is related to images being loaded, another thread mentioned setting centeredSlides: true fixes it, which it does, however, I don’t want my slides centered.

Anyway to solve this in React? SwiperReact?

The solution mentioned here changes the way my slides are arranged, I have a combination of

  centeredSlides: true,
  centeredSlidesBounds: true,

using this method fixes the initial bug but introduces another where my slides are not aligned properly. I only needed the correct index so my workaround was to calculate the index based on the progress and slides.length, i have done this in the transitionEnd hook (the progress event fires too often for my needs), the other hooks didn’t work for me.

// edit: turns out the snapIndex is also usable in my case

I currently experienced the same problems like as many people did and also looked through the issues but no results. #2571, #1257, #534 Finally, I found out a way to do it, a better way to do it guys!. By setting the snapGrid settings as same as the slidesGrid settings after the swiper initialized. And then the swiper will work as what you expected.

const swiper = new Swiper(
    '.awesome-swiper', 
    {
        init: false,
        direction: 'horizontal',
        speed: 700,
        slidesPerView: 'auto',
        spaceBetween: 80,
    }
);

swiper.init();
swiper.snapGrid[swiper.snapGrid.length - 1] = swiper.slidesGrid[swiper.slidesGrid.length - 1];

or even completely replacing it by cloning the settings.

// can do this way
swiper.snapGrid = swiper.slidesGrid.slice(0);

// or ES6 way
swiper.snapGrid = [...swiper.slidesGrid];

this work for me, but with a little adjustment: I placed this line this.snapGrid = [...this.slidesGrid]; inside of the reachEnd swiper event, like this:

const swiper = new Swiper('.awesome-swiper', {
    direction: 'horizontal',
    speed: 700,
    slidesPerView: 'auto',
    spaceBetween: 80,
    on: {
      reachEnd: function() {
        this.snapGrid = [...this.slidesGrid];
      },
    }
}

This one didn’t work for me. When I go to the last item I have to click twice to reach the last element. The solution is to click on the next button through javascript when I reach the reachEnd function. It works only with the setTimeout function because of no reason Here we go:

       on: {
          reachEnd: function() {
            this.snapGrid = [...this.slidesGrid];
            setTimeout(() => {
              document.querySelector('.swiper-button-next').click()
              clearTimeout()
            }, 1);
          },
        }