今回は以下のような、スクロールしてスライドが画面外から外れたときにスライドの動きが停止するような動きを実装します。今回は特定のオブジェクトに対してスクロールイベントを検知することができるIntersection Observer APIを利用します。
See the Pen Stoping Swiper off-screen using Intersection Observer API by Natsu (@enbwdzmk-the-bashful) on CodePen.
今回の実装では、スクロールして画面外から外れたときにスライドの動きが停止するのが目視できるように、スライドの高さの画面内領域が30%を下回った時に動きが停止するように実装しています。逆にスクロールしてスライドの高さの画面内領域が30%以上画面に再び入った場合は動きが再開します。以下、コードの解説です。
まず、以下のHTMLをindex.htmlに記述します。swiperライブラリを読み込み、swiperスライドを6枚用意し、その下に.scrollというスクロールを生み出すためのdivを用意しています。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@8/swiper-bundle.min.css"/>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="swiper">
<div class="swiper-wrapper">
<div class="swiper-slide">スライド1</div>
<div class="swiper-slide">スライド2</div>
<div class="swiper-slide">スライド3</div>
<div class="swiper-slide">スライド4</div>
<div class="swiper-slide">スライド5</div>
<div class="swiper-slide">スライド6</div>
</div>
</div>
<div class="scroll"></div>
<script src="https://cdn.jsdelivr.net/npm/swiper@8/swiper-bundle.min.js"></script>
<script src="script.js"></script>
</body>
</html>
続いて、以下のCSSをstyle.cssに記述します。.swiper-slideと.scrollにそれぞれ任意のCSSを当てていきます。
.swiper-slide {
width: 264px;
height: 332px;
background-color: #1B224C;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
}
.scroll {
width: 100%;
height: 2000px;
margin-top: 100px;
background-color: orange;
}
最後に、swiperを動かすjsコード、およびswiperを画面外で停止させるためのIntersection Observer APIのコードをscript.jsに記述します。Intersection Observer APIはスクロールイベントの実装で最近よく用いられている手法であり、コードの書き方も沢山記事が出ていますので、分からない方は調べてみてください。
// Swiper
const swiper = new Swiper('.swiper', {
loop: true,
speed: 1000,
autoplay: {
delay: 1000,
disableOnInteraction: false,
},
centeredSlides: true,
slidesPerView: 'auto',
spaceBetween: 24,
});
// autoplayを停止。ページが読み込まれたときには再生しないようにするため
swiper.autoplay.stop();
// Intersection Observerの設定
let options = {
root: null,
rootMargin: '0px',
threshold: 0.3 // ターゲット要素の画面内領域が30%を下回った時にcallbackを発火
};
let observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
// ビューポート内に入ったときの処理
swiper.autoplay.start();
} else {
// ビューポートから出たときの処理
swiper.autoplay.stop();
}
});
}, options);
// スライダーを監視対象に追加
observer.observe(document.querySelector('.swiper'));
今回は、一番最後の行で、IntersectionObserverクラスのobserveメソッドに対して、.swiper(スライドを包括する要素)を引数として渡しているため、スライドの画面内有無を検知できています。25-35行目で、.swiperが画面内にあるとき、ないときの処理(swiperクラスのautoplayパラメータに対して関数を実行)を行っています。
また、Intersection Observer APIでは交差範囲等を指定するoptionsを指定できる(18-23、35行目)のですが、ここでthreshold: 0.3としているため、スライドの高さの画面内領域が30%になった時点で動きが停止します。今回は停止する様子が目視できるように設定しましたが、通常は必要ないと思います。
以上が、Intersection Observer APIを利用して、Swiperを画面外で停止させる方法となります!実装機会は少ないかもしれませんが、Swiper以外にも応用できる手法ですので、ご参考までにどうぞ。