swiper
swiper copied to clipboard
Combination of [loop, slideToClickedSlide, centeredSlides] doesn't show elements properly
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:
- Use script to add swiper component
- Use:
- loop: true
- slidesPerView: 5
- slideToClickedSlide: true
- centeredSlides: true
- 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
I have the same problem.
Same for me
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.
Also experiencing the same issue here
Same for me, also I experience this issue when dragging slides. Does someone have a solution?
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"
I have the same problem.
Same issue here, even worst when you use slidePerView: auto
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.
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.
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.
Does anyone have a stand-in solution for this?
In my case, I downgrade back to v8 and use the Angular component
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
Just asking... has there been any progress on this?
Same issue here. Did anyone find a solution?
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
initialSlideto 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.
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,
has there been any progress on this?
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>
);
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
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
}
});
I experience same issue
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.
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);
}
})