swiper.jsで自動再生しながらループするサムネイル付きスライダーを実装した時の備忘録

#Swiper.js
https://swiperjs.com/

##version

7.2.0 ~ 7.3.1
##installation
以下の3択。

- npm
- CDN
- assetsをDLする

7系にアップデートされた際、```.swiper-container```が```.swiper```に代わり、CDN派一同騒然という事態が発生した事例があるので、CDNは要注意。

#自動再生しながらループするサムネイル付きスライダー
swiper.jsのサムネイル付きのループするスライドのdemoでは、サムネイルもhtmlで記述している。
でもサムネイルまで記述するのがめんどくさいし、スライドを変更することになった時に両方いじらないといけなくなる。
なので、メインスライドのスライドを複製する。
###Swiper.jsのdemo

https://codesandbox.io/s/ozbh1

https://codesandbox.io/s/dmobn

##Demo

<p class="codepen" data-height="300" data-default-tab="js,result" data-slug-hash="LYzPGNM" data-user="brassyk" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/brassyk/pen/LYzPGNM">
  Untitled</a> by brassyk (<a href="https://codepen.io/brassyk">@brassyk</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

```html:index.html
<!-- メインスライド -->
<div style="--swiper-navigation-color: #fff; --swiper-pagination-color: #fff;" class="swiper mySwiper2">
    <div class="swiper-wrapper">
        <div class="swiper-slide">
            <img src="https://swiperjs.com/demos/images/nature-1.jpg" />
        </div>
        <div class="swiper-slide">
            <img src="https://swiperjs.com/demos/images/nature-2.jpg" />
        </div>
        <div class="swiper-slide">
            <img src="https://swiperjs.com/demos/images/nature-3.jpg" />
        </div>
    </div>
    <div class="swiper-button-next"></div>
    <div class="swiper-button-prev"></div>
</div>
<!-- サムネイル -->
<div thumbsSlider="" class="swiper mySwiper">
    <!-- .mySwiper2の.swiper-wrapperをcloneNodeしてここにappendChildする -->
</div>

```

##サムネイルのスライドを生成する
メインスライドのwrapperごと複製し、サムネイルのコンテナ内へ追加する。
###メインスライドのスライドを複製する
cloneNodeでwrapperごと複製する。このとき、deepをtrueにしていることを確認。
falseになっていると、小ノードが複製されない。
DOM4ではdefaultがtrueで省略可能だったが、現在は必須なので要注意。
###サムネイルのコンテナへ追加
cloneNodeで複製したノードは、メソッドで追加するまで親ノードを持てずドキュメントの一部にもなれない。
```.mySwier```へ、appendChildで追加する。

```javaScript:swiper-config.js
const mySwiper2_wrapper = document.querySelector(".mySwiper2 .swiper-wrapper"),
      mySwiper_container = document.querySelector(".mySwiper"),
      clone = mySwiper2_wrapper.cloneNode(true);
mySwiper_container.appendChild(clone);

```

https://developer.mozilla.org/ja/docs/Web/API/Node/cloneNode

https://developer.mozilla.org/ja/docs/Web/API/Node/appendChild

##Paramaterを設定する
スライドのサイズはいつもCSSで指定しているので、slidesPerViewはauto。
```slidesPerView: "auto"```のとき、loopedSlidesを設定する必要がある。
さらに、サムネイルは1列で表示させたい。
しかし、スライドの数が増減したときにいちいち変えるのはめんどくさい。
今回はメインスライドを複製するためにwrapperを取得しているので、childNodes.lengthで子ノードの数を取得する。
あとは適当にいい感じにする。

```javaScript:swiper-config.js
    const swiper = new Swiper(".mySwiper", {
    loop: false,
    spaceBetween: 10,
    slidesPerView: mySwiper2_wrapper.childNodes.length,
    freeMode: true,
    watchSlidesProgress: true
    });
    const swiper2 = new Swiper(".mySwiper2", {
    autoplay: {
        delay: 5000,
        disableOnInteraction: false
    },
    slidesPerView: "auto",
    centeredSlides: true,
    loop: true,
    loopedSlides: mySwiper2_wrapper.childNodes.length,
    spaceBetween: 10,
    speed: 800,
    navigation: {
        nextEl: ".swiper-button-next",
        prevEl: ".swiper-button-prev"
    },
    thumbs: {
        swiper: swiper
    }
    });
},false);
```

#ついでに
IntersectionObserverでビューポートを監視し、
ビューポートにスライドが交差してからautoplay.start()させてみる。(ちょっと適当)

```javaScript:swiper-config.js
on: {
    afterInit: (mySwiper2) => {
        mySwiper2.autoplay.stop();
        const options = {
            root:       null,
            rootMargin: '-50%',
            thredhold:  0
        };
        const target = document.querySelector('.mySwiper2');
        const observer = new IntersectionObserver(callback, options);
        observer.observe(target);
        function callback(entries, object) {
            entries.forEach(function(entry, i) {
                if (!entry.isIntersecting) return;
                const target = entry.target;
                mySwiper2.autoplay.start();
                object.unobserve(target);
            });
        };
    },
}
```