How Do I Stop Swiper.JS Thumbs From Automatically Transitioning?

Viewed 1838

I have a swiper.js slider made in react. If I have 8 images in the swiper and then I navigate to the 8th thumbnail and click on the 7th thumb it will slider the thumbnail part up. Is there a way to prevent this behavior from happening?

What I want to do is for it to only auto slide if there are more slides up or down available. For example, if I have 5 thumbnails and slide [2, 3, 4, 5, 6] are visible, if I select slide 6 it would move over and show slide 7 available and if I select slide 2 it would slide over and show slide 1. That is the only movement I want it to do. Is that feature available in the docs?

          <div className="mainSliderWrap">
            <Swiper
              pagination
              onSlideChange={swiper => {
                setImageSelectedIndex(swiper.activeIndex + 1)
                return true
              }}
              thumbs={{ swiper: thumbsSwiper }}>
              {products.images.map((product, index) => (
                <SwiperSlide key={product.originalSrc}>
                  <img
                    className={classes.mainSliderImg}
                    ref={el => {
                      imagesRef.current[index] = el as HTMLImageElement
                    }}
                    src={product.originalSrc}
                    data-zoom={product.originalSrc}
                    alt={product.title}
                    height={360}
                    width={360}
                  />
                </SwiperSlide>
              ))}
            </Swiper>
          </div>
          <div
            className={[
              "productSlider",
              ProductSliderOrientation(width) === "horizontal" &&
                "horizontalProductSlider"
            ].join(" ")}>
            <div className="swiper-button-next mainProdNext" />
            <div className="swiper-button-prev mainProdPrev" />
            <Swiper
              direction={ProductSliderOrientation(width)}
              touchRatio={1}
              threshold={10}
              slidesPerView={slidesPerView}
              spaceBetween={15}
              navigation={{
                nextEl: ".mainProdNext",
                prevEl: ".mainProdPrev"
              }}
              onSwiper={setThumbsSwiper}
              breakpoints={{
                0: {
                  spaceBetween: 10,
                  slidesOffsetBefore: 20,
                  slidesOffsetAfter: 20
                },
                576: {
                  spaceBetween: 10,
                  slidesPerView: 5
                },
                768: {
                  touchRatio: 0,
                  slidesPerView: 5
                },
                992: {
                  touchRatio: 1,
                  slidesPerView: 5
                },
                1200: {
                  touchRatio: 0,
                  slidesPerView: 5
                }
              }}>
              {products &&
                products.images.map(product => (
                  <SwiperSlide key={product.originalSrc}>
                    <ProductImage
                      image={product}
                      alt={products.title}
                      moduleClass={classes.productImagePick}
                      gatsbyImageClass={classes.productImagePickGatsby}
                    />
                  </SwiperSlide>
                ))}
            </Swiper>
          </div>
        </div>
      </div>
1 Answers

It looks like there is no way to implement thumbnails with this behavior without manipulating data. So idea is when you change a thumbnail you need to reorder data in order to show next/previous thumb.

export default function App() {
  const [thumbsSwiper, setThumbsSwiper] = useState(null);

  const [data, setData] = useState([
    "https://swiperjs.com/demos/images/nature-1.jpg",
    "https://swiperjs.com/demos/images/nature-2.jpg",
    "https://swiperjs.com/demos/images/nature-3.jpg",
    "https://swiperjs.com/demos/images/nature-4.jpg",
    "https://swiperjs.com/demos/images/nature-5.jpg",
    "https://swiperjs.com/demos/images/nature-6.jpg",
    "https://swiperjs.com/demos/images/nature-7.jpg",
    "https://swiperjs.com/demos/images/nature-8.jpg",
    "https://swiperjs.com/demos/images/nature-9.jpg",
    "https://swiperjs.com/demos/images/nature-10.jpg"
  ]);

  return (
    <>
      <Swiper
        style={{
          "--swiper-navigation-color": "#fff",
          "--swiper-pagination-color": "#fff"
        }}
        loop={false}
        spaceBetween={10}
        navigation={true}
        thumbs={{ swiper: thumbsSwiper }}
        className="mySwiper2"
        onSlideChange={(e) => {
          if (e.realIndex % 3 === 0) {
            // move first element to the end
            const newData = [...data];
            newData.push(newData.shift());
            setData(newData);
            e.slideTo(e.realIndex - 1);
          }
          if (e.realIndex === 0) {
            // move last element to the beginning
            const newData = [...data];
            newData.unshift(newData.pop());
            setData(newData);
            e.slideTo(e.realIndex + 1);
          }
        }}
      >
        {data.map((img) => (
          <SwiperSlide key={img}>
            <img src={img} />
          </SwiperSlide>
        ))}
      </Swiper>
      <Swiper
        onSwiper={setThumbsSwiper}
        loop={false}
        loopedSlides={1}
        spaceBetween={10}
        slidesPerView={4}
        freeMode={false}
        watchSlidesVisibility={true}
        watchSlidesProgress={true}
        className="mySwiper"
      >
        {data.map((img) => (
          <SwiperSlide key={img}>
            <img src={img} />
          </SwiperSlide>
        ))}
      </Swiper>
    </>
  );
}

Here is a codesandbox

This is a quick example only. I hope it will help you.

Related