swiper
swiper copied to clipboard
Autoplay and slidesPerView auto only autoslides a single slide
- Swiper Version: 6.4.10
- Platform/Target and Browser Versions: KDE Neon 5.20, Firefox 85.0 (64-bit) & Chrome Version 88.0.4324.96 (Official Build) (64-bit)
What You Did
Enabled autoplay in combination with slidesPerView={'auto'}.
Example: https://codesandbox.io/s/naughty-swanson-6dz2i
Expected Behavior
The slider will autoslide.
Actual Behavior
Now the slider will only move 1 slide, and then stop autosliding.
Disabling or changing the value of slidesPerView (anything but auto works) fixes the issue. Also, calling update(), resizing the window (which internally also forces an update if I'm not mistaken) or even switching to another tab and coming back will let the slider move 1 slide again.
The plot thickens. I figured it had to do something with my hack to work around the changing sizes of the swiper-slide-current slide. Here I run swiper.update() 50ms after a slideChange event. So, I did a quick experiment using the JS based Swiper, where I could not replicate the bug. So I figured it was a React-related issue. I found #3977, where the author also uses autoplay with slidesPerView auto; so I took his code for a quick test as well:
JS based test: https://codesandbox.io/s/amazing-newton-kiejf?file=/index.html - All fine and working with the swiper.update()
Second React test: https://codesandbox.io/s/strange-bash-g715w - Broken when adding the onSlideChange, but working with slidesPerView on auto
So I guess it's a little more complicated than I thought... So it seems to be react-specific, and having to do with the combination of autoplay, slidesPerView on auto and the swiper.update call on slideChange...
Similar workaround for the slide width found here: #1861
It explains the jumpyness I had also experienced; but since my slide width change is not that big, I just took it for granted. Note that he also uses the swiper.update() after a slidechange (although he uses onSlideChangeEnd). Here autoplay also appears to work; which is consistent with my findings that it only breaks when using React.
For anyone stumbling across this; I've created a workaround by manually implementing the basics of the autoplay feature: https://codesandbox.io/s/interesting-golick-pkki2
It takes the same event used in the source code of Swiper: https://github.com/nolimits4web/swiper/blob/e39d8e924048fd043377054e0a2d6d9496bf11aa/src/components/autoplay/autoplay.js#L167-L175
And uses the basic idea from this SO answer to pause and unpause: https://stackoverflow.com/a/21278007
I'm not saying it's the best solution, but it works for me.
I'd still like the original bug to be worked out though :)
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
@contributers any word on the bug? Or will we just let it go stale? :(
Any update on this issue?
hi. the same problem but is desided to write special code to handle it. this worke for me: slidesPerView={here,you must find your window width divided by width of your sliders} i wrote a hook to calculate width for me: :see the end of code for hook created to handle the size and then see slidesPerVeiw in swiper to understand usage"
import { useState, useEffect } from "react";
import React from "react";
import { Swiper, SwiperSlide } from "swiper/react";
import "swiper/css";
import "swiper/css/navigation";
import "swiper/css/scrollbar";
import "swiper/css/free-mode";
import SwiperCore, { Autoplay, FreeMode, Navigation, Scrollbar } from "swiper";
import { styled } from "@mui/material";
SwiperCore.use([Scrollbar, FreeMode, Autoplay, Navigation]);
//-----------style to swiper by: styled()
let Swip = styled(Swiper)(({ theme }) => ({
padding: 17,
width: "90%",
"& .swiper-wrapper": { padding: 0 },
}));
export default function Brands() {
const { width } = useWindowDimensions();
return (
<Swip
autoplay={{
delay: 3000,
disableOnInteraction: false,
}}
navigation={true}
spaceBetween={10}
centeredSlides={true}
loop={true}
freeMode={true}
slidesPerView={width>1700?1700/200:Math.floor(width/200)}
scrollbar={{
hide: false,
}}
>
<SwiperSlide>
<div
style={{ width: 150, height: 100, backgroundColor: "lightgreen" }}
/>
</SwiperSlide>
<SwiperSlide>
<div
style={{ width: 150, height: 100, backgroundColor: "lightblue" }}
/>
</SwiperSlide>
<SwiperSlide>
<div
style={{ width: 150, height: 100, backgroundColor: "darkgreen" }}
/>
</SwiperSlide>
<SwiperSlide>
<div
style={{ width: 150, height: 100, backgroundColor: "purple" }}
/>
</SwiperSlide>
<SwiperSlide>
<div
style={{ width: 150, height: 100, backgroundColor: "pink" }}
/>
</SwiperSlide>
<SwiperSlide>
<div
style={{ width: 150, height: 100, backgroundColor: "brown" }}
/>
</SwiperSlide>
<SwiperSlide>
<div
style={{ width: 150, height: 100, backgroundColor: "yellow" }}
/>
</SwiperSlide>
<SwiperSlide>
<div
style={{ width: 150, height: 100, backgroundColor: "red" }}
/>
</SwiperSlide>
<SwiperSlide>
<div
style={{ width: 150, height: 100, backgroundColor: "black" }}
/>
</SwiperSlide>
<SwiperSlide>
<div
style={{ width: 150, height: 100, backgroundColor: "green" }}
/>
</SwiperSlide>
<SwiperSlide>
<div
style={{ width: 150, height: 100, backgroundColor: "blue" }}
/>
</SwiperSlide>
</Swip>
);
}
function getWindowDimensions() {
const { innerWidth: width, innerHeight: height } = window;
return {
width,
height,
};
}
function useWindowDimensions() {
const [windowDimensions, setWindowDimensions] = useState(
getWindowDimensions()
);
useEffect(() => {
function handleResize() {
setWindowDimensions(getWindowDimensions());
}
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
return windowDimensions;
}
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
@contributers any word on the bug? Or will we just let it go stale? :(
Swiper v9 comes with fully reworked autoplay module. If you have similar issues in Swiper 9, open a new issue with a CodeSandbox showing the issue.