swiper icon indicating copy to clipboard operation
swiper copied to clipboard

Combination of [loop, slideToClickedSlide, centeredSlides] doesn't show elements properly

Open amaksimovich2 opened this issue 2 years ago • 33 comments

Check that this is really a bug

  • [X] I confirm

Reproduction link

https://codesandbox.io/s/swiper-slides-per-view-auto-forked-sy45mf

Bug description

I want to create infinite slider with possibility to select element by click. Steps to reproduce:

  1. Use script to add swiper component
  2. Use:
  • loop: true
  • slidesPerView: 5
  • slideToClickedSlide: true
  • centeredSlides: true
  1. Click on right or left element several times

Expected Behavior

Selected element always in center. List of elements have infinite behavior

Actual Behavior

Selected element always in center. After some clicks there are empty space except new elements

Check example here

Swiper version

11.0.3

Platform/Target and Browser Versions

Wondows/Chrome 118.0.5993.118

Validations

  • [X] Follow our Code of Conduct
  • [X] Read the docs.
  • [X] Check that there isn't already an issue that request the same feature to avoid creating a duplicate.
  • [X] Make sure this is a Swiper issue and not a framework-specific issue

Would you like to open a PR for this bug?

  • [ ] I'm willing to open a PR

amaksimovich2 avatar Oct 30 '23 19:10 amaksimovich2

I have the same problem.

lx0427 avatar Nov 01 '23 02:11 lx0427

Same for me

marvinerkes avatar Nov 18 '23 13:11 marvinerkes

I'm having the same issue, but I've noticed that it happens independently of slideToClickedSlide. I've tried downgrading to 10.3.1 but it has the same issue and additionally slideToClickedSlide behaves erratically, scrolling in the wrong direction on occasion.

s-ol avatar Nov 20 '23 10:11 s-ol

Also experiencing the same issue here

tdambra avatar Nov 20 '23 22:11 tdambra

Same for me, also I experience this issue when dragging slides. Does someone have a solution?

valeryq avatar Nov 21 '23 17:11 valeryq

I got this bug as well,

  • In the beginning, when you click on "slide 8", it move to the left but doesn't create the "slide 6"
image

BangNguyen1992 avatar Nov 28 '23 17:11 BangNguyen1992

I have the same problem.

seungkum avatar Nov 30 '23 08:11 seungkum

Same issue here, even worst when you use slidePerView: auto

PubliAlex avatar Nov 30 '23 10:11 PubliAlex

It seems that the loop and centeredSlides props are not good friends together, especially when setting slidePerView to auto

Since I have responsive slides, on larger screens where conditions are met it works mostly fine, but in mobile it fails every time.

Take a look at this example from Swiper original demos with some custom slider parameters:

{
      slidesPerView: "auto",
      loop: true,
      centeredSlides: true,
      ...
}

https://codepen.io/arl1nd/full/qBvBdRv

Play with viewport width and refresh the page, it will randomly set centered slide which sometimes is last slide, and sometimes is first slide, on some other cases it fails to create the loop as well.

Hopefully the team will take into consideration this soon and provide a fix.

arl1nd avatar Dec 21 '23 15:12 arl1nd

Also facing this issue in React, with fixed width slides and Slider props:

  • modules={[FreeMode]}
  • freeMode={{ enabled: true, sticky: true, momentum: false, momentumBounce: false, minimumVelocity: 100 }}
  • loop
  • centeredSlides
  • slidesPerView="auto"

It only happens if I drag. Arrow buttons with swiper.slideNext() or swiper.slidePrev() work fine. Looks like the looping doesn't fill enough slides in time for drag.

DevTakao avatar Dec 28 '23 05:12 DevTakao

The issue still persists in the latest version (11.0.6). I'm using these options

 {
  slidesPerView: 'auto',
  loop: true,
  slideToClickedSlide: true,
}

When I remove one of these options, everything seems to work fine. The problem also seems to only occur when clicking the last slides. So it feels to me like the loop options does not calculate the "looped" slides correctly.

StevenVerbiest avatar Feb 06 '24 11:02 StevenVerbiest

Does anyone have a stand-in solution for this?

anthony-branch avatar Feb 13 '24 14:02 anthony-branch

In my case, I downgrade back to v8 and use the Angular component

BangNguyen1992 avatar Feb 13 '24 16:02 BangNguyen1992

I have params:

                                                        slidesPerView={5}
							initialSlide={initialSLideTwo}
							direction={'vertical'}
							loop={true}
							modules={[Navigation]}
							onSlideChange={(slide) => handleSlideChange(slide, 2)}
							centeredSlides={true}
							navigation={true}

and i had same problem. I add centeredSlidesBounds. It shouldn't work as documentation says, but it works for me but there is another problem with active slide

Reg93 avatar Feb 15 '24 06:02 Reg93

Just asking... has there been any progress on this?

jaxtheking avatar Mar 11 '24 12:03 jaxtheking

Same issue here. Did anyone find a solution?

pgonzalez-santiago avatar Apr 23 '24 13:04 pgonzalez-santiago

The problem in my case is centeredSlides, if I do not set that prop then the behaviour is infinite and there are no gaps. But in that case, if working i.e. in a desktop then the active element is always on the left. I tried using initialSlide but that just moves the first visible slide to whatever position in the array. Not a solution. Checking other issues it seems this problem was already in version 10, and although version 11 of Swiper technically has a different loop version, the issue still persists.

As a workaround, you could do this:

  • Double the array i.e. if the array was 10 elements, now it is is 20: const doubledItems = items.concat(items)
  • Set the initialSlide to be 10 aka the first element of the second array

This then looks like the loop is working fine, because the last elements of the original array are seen on the left, and the elements that go to the right are still there. This does not fix the issue though, because if you scroll too much to the left or right then the 'items appearing on demand' issue shows up.

Tevvek avatar Apr 25 '24 15:04 Tevvek

It's even worse when you have this setup:

modules: [Navigation, Mousewheel, FreeMode],
      direction: 'horizontal',
      slidesPerView: "auto",
      freeMode: {
        enabled: true,
        sticky: true,
        momentum: true,
      },
      loop: true,
      centeredSlides: true,

wisniewski94 avatar May 22 '24 08:05 wisniewski94

has there been any progress on this?

Abdulrrahman avatar Jun 24 '24 07:06 Abdulrrahman

I fix it in next way -> onClick={() => swiperRef.current?.swiper.slideToLoop(index)}

const swiperRef = useRef<SwiperRef | null>(null);

return (
    <Swiper
        ref={swiperRef}
        modules={[Keyboard, Mousewheel, Pagination, Navigation]}
        **slidesPerView={"auto"}**
        slidesPerGroup={1}
        spaceBetween={0}
        **centeredSlides={true}**
        **loop={true}**
    >
        {personas.map((item, index) => (
            <SwiperSlide
                **onClick={() => swiperRef.current?.swiper.slideToLoop(index)}**
                key={item.id}
            > 
                <Image src={item.images.main}/>
            </SwiperSlide>
        ))}
    </Swiper>
);

ChernenkoDmitriy avatar Jun 27 '24 10:06 ChernenkoDmitriy

I fix it in next way -> onClick={() => swiperRef.current?.swiper.slideToLoop(index)}

const swiperRef = useRef<SwiperRef | null>(null);

return (
    <Swiper
        ref={swiperRef}
        modules={[Keyboard, Mousewheel, Pagination, Navigation]}
        **slidesPerView={"auto"}**
        slidesPerGroup={1}
        spaceBetween={0}
        **centeredSlides={true}**
        **loop={true}**
    >
        {personas.map((item, index) => (
            <SwiperSlide
                **onClick={() => swiperRef.current?.swiper.slideToLoop(index)}**
                key={item.id}
            > 
                <Image src={item.images.main}/>
            </SwiperSlide>
        ))}
    </Swiper>
);

No, you do not. You just show one slide per group. And you have not even faced the issue

myznikovgleb avatar Jul 08 '24 15:07 myznikovgleb

This kinda work for me.

var swiper = new Swiper(".mySwiper", {
        slidesPerView: "auto",
        spaceBetween: 30,
        loop: true,
        slidesPerView: 5,
        centeredSlides: true,
        on: {
          click: (swiper) => {
            if (swiper.clickedIndex > swiper.activeIndex) {
              swiper.slideNext();
            } else {
              swiper.slidePrev();
            }
          }
        },
        pagination: {
          el: ".swiper-pagination",
          clickable: true
        }
      });

SmithChebesta avatar Jul 23 '24 23:07 SmithChebesta

I experience same issue

donguk87 avatar Aug 07 '24 11:08 donguk87

I found a solution. The problem lies in using the "slideToClickedSlide" option. The "slideToClickedSlide" option seems to have a bug when used with "loop" option and "centeredSlides" option.

Instead of using the "slideToClickedSlide" option, use "swiper.slideToLoop(index)" within the onClick event of each slide.

donguk87 avatar Aug 07 '24 12:08 donguk87

Here's how I got this problem solved:

let swiper = new Swiper(".swiper", {
  loop: true,
  slidesPerView: "auto",
  spaceBetween: 16,
  centeredSlides: true,
});

swiper.slides.forEach(slide => {
  slide.onclick = () => {
    slider.slideToLoop(slide.dataset.swiperSlideIndex);
  }
})

luteet avatar Aug 08 '24 07:08 luteet