Skip to content

fix(thumbs): Update slide classes in virtualUpdate event#8141

Merged
nolimits4web merged 1 commit intonolimits4web:masterfrom
nWacky:fix-virtual-updates-pr
Jan 12, 2026
Merged

fix(thumbs): Update slide classes in virtualUpdate event#8141
nolimits4web merged 1 commit intonolimits4web:masterfrom
nWacky:fix-virtual-updates-pr

Conversation

@nWacky
Copy link
Copy Markdown
Contributor

@nWacky nWacky commented Jan 12, 2026

Swiper has virtual and thumbnail modules.

When using both modules:

  1. slide 1 is highlighted
  2. scroll far to the left.
    virtual module removes slide 1 dom node
  3. scroll back
    virtual module recreates slide 1 dom node

Currently: slide 1 stops being highlighted as the selected slide.

Expected: slide 1 is highlighted as the selected slide after scrolling.

Also, clicking "Next slide" does not highlight the next slide as current.
Expected for it to be highlighted.

swiper.issue.mp4
Test html page

Copy to playground/core/index.html

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Swiper Playground</title>
    <meta name="viewport" content="width=device-width" />
    <style>
      html,
      body {
        position: relative;
        height: 100%;
      }

      body {
        background: #eee;
        font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
        font-size: 16px;
        color: #000;
        margin: 0;
        padding: 0;

        box-sizing: border-box;
        display: flex;
        flex-flow: column;
        padding: 1rem;
        height: 100dvh;
        gap: 2rem;
      }

      .swiper {
        width: 100%;
        height: 100%;
      }

      .swiper.thumbs {
        box-sizing: border-box;
        padding: 0 calc(var(--swiper-navigation-size) + 1rem);
        height: 30%;
      }

      .image-slide {
        display: flex !important;
        align-items: center;
        justify-content: center;
        background: #fff;
        text-align: center;
        font-size: 18px;
      }

      .thumb-slide.swiper-slide {
        display: flex;
        align-items: center;
        justify-content: center;
        background: #d3d3d3;
      }

      .thumb-slide.swiper-slide-thumb-active {
        background: #76ff8d;
      }
    </style>
  </head>

  <body>
    <div class="images swiper">
      <div class="swiper-wrapper">
        <!-- <div class="swiper-slide image-slide">Slide 1</div> -->
      </div>

      <div class="swiper-button-next"></div>
      <div class="swiper-button-prev"></div>
    </div>

    <div class="thumbs swiper">
      <div class="swiper-wrapper">
        <!-- <div class="swiper-slide thumb-slide">Thumbnail 1</div>  -->
      </div>
      <div class="swiper-button-next"></div>
      <div class="swiper-button-prev"></div>
    </div>

    <script type="module">
      // eslint-disable-next-line
      import "swiper/swiper-bundle.css";

      // eslint-disable-next-line
      import Swiper from "swiper/swiper-bundle.mjs";

      window.swiperThumbs = new Swiper(".thumbs", {
        slidesPerView: 4,
        spaceBetween: 10,
        navigation: {
          nextEl: ".swiper-button-next",
          prevEl: ".swiper-button-prev",
        },
        mousewheel: true,
        freeMode: true,
        virtual: {
          slides: (function () {
            const slides = [];
            for (var i = 0; i < 50; i += 1) {
              slides.push(`Thumbnail ${i + 1}`);
            }
            return slides;
          })(),
          renderSlide: (slide, index) => {
            let e = document.createElement("div");
            e.classList.add("thumb-slide", "swiper-slide");
            e.innerText = slide;
            return e;
          },
          cache: false,
        },
        watchSlidesProgress: true,
      });

      window.swiperImages = new Swiper(".images", {
        slidesPerView: 1,
        spaceBetween: 10,
        thumbs: {
          swiper: window.swiperThumbs,
        },
        navigation: {
          nextEl: ".swiper-button-next",
          prevEl: ".swiper-button-prev",
        },
        virtual: {
          slides: (function () {
            const slides = [];
            for (var i = 0; i < 50; i += 1) {
              slides.push(`Slide ${i + 1}`);
            }
            return slides;
          })(),
          renderSlide: (slide, index) => {
            let e = document.createElement("div");
            e.classList.add("image-slide", "swiper-slide");
            e.innerText = slide;
            return e;
          },
        },
      });
    </script>
  </body>
</html>

In this PR:

When virtual swiper is enabled, update slide classes when virtual module emits the virtualUpdate event.
Do not scroll to the next slide in virtualUpdate event listener.

@nWacky nWacky changed the title fix: Update slide classes in virtualUpdate (virtual module) fix: Update slide classes in virtualUpdate event (from virtual module) Jan 12, 2026
@nWacky nWacky changed the title fix: Update slide classes in virtualUpdate event (from virtual module) fix(thumbnail): Update slide classes in virtualUpdate event Jan 12, 2026
@nWacky nWacky changed the title fix(thumbnail): Update slide classes in virtualUpdate event fix(thumbs): Update slide classes in virtualUpdate event Jan 12, 2026
@nolimits4web nolimits4web merged commit 9752771 into nolimits4web:master Jan 12, 2026
3 checks passed
@nolimits4web
Copy link
Copy Markdown
Owner

Merged, thank you!

@nWacky nWacky deleted the fix-virtual-updates-pr branch January 13, 2026 07:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants