サムネイル

IntersectionObserverを使ったスクロールイベント実装

従来、スクロールに合わせて要素を操るには scroll というイベントを利用していました。ただ、それだと画面サイズが変わったら再計算しないといけなかったり、スクロールするたびに関数を呼び出すので、パフォーマンスへの悪影響が懸念されていました。
それを解決するが本日紹介するIntersectionObserverです。

IntersectionObserverって?

IntersectionObserverとは、Intersection:交差 , Observer:観察者という意味があります。つまり、特定の要素が指定領域内に入ったかどうかを検知するAPIのことです。なので、スクロールイベント等を実装するときに使用するAPIです。
https://developer.mozilla.org/ja/docs/Web/API/IntersectionObserverAPI

IntersectionObserverの基本的な使い方

基本的には IntersectionObserver を呼び出して、第1引数に実行したい関数、第2引数にオプション設定を記述します

const options = {
  root: document.querySelector('#scrollArea'),
  rootMargin: '0px',
  threshold: [0.2, 1.0]
}
 
const observer = new IntersectionObserver(callback, options);

options オブジェクトは、以下のフィールドがあります:

root

ターゲットとなる要素が見えるかどうかを判定するためのベース部分を指定します。デフォルトはブラウザのビューポートです。

rootMargin

交差を計算する際は、実際は基準要素の領域にここで指定した余白値を足した領域が計算基準となる。つまり例えばここに正の値を指定すれば、実際に見える前に交差していると判定させることができる。デフォルトは 0px です。

threshold

関数を実行するタイミングを 0〜1 の間で記述します。コールバックを実行する交差の閾値リスト。交差の割合が閾値を上回るか下回ったときのみコールバック関数が実行される。[0, 0.5, 1] のように配列形式でも記述できます。上の例でいうと、見えている割合が20%および100%を上回るか下回ったときにコールバックが実行される。デフォルトでは0 です。

IntersectionObserverの設定

では、実際にIntersecftionObserverを設定し、要素の監視をしてみましょう。

// 交差を監視する要素の取得
const boxes = document.querySelectorAll(".box");

const options = {
  root: null, // 今回はビューポートをルート要素とする
  rootMargin: "-50% 0px", // ビューポートの中心を判定基準にする
  threshold: 0 // 閾値は0
};
const observer = new IntersectionObserver(doWhenIntersect, options);

// それぞれのboxを監視する
boxes.forEach(box => {
  observer.observe(box);
});

/**
 * 交差したときに呼び出す関数
 * @param entries
 */
function doWhenIntersect(entries) {
  entries.forEach(entry => {

    // --------------------- この構文が肝 ------------------------------
    // 交差検知をしたもののなかで、isIntersectingがtrueのDOMにactiveクラスを付与。そうでなければ、activeクラスを取り除く
    if (entry.isIntersecting) {
      entry.target.classList.add("active");
    } else {
      entry.target.classList.remove("active");
    }
    // ---------------------------------------------------------------------

  });
}


.box {
  option: 0;
}
.box.active {
  option: 1;
}

最後までお読みいただきありがとうございました。
参考になれば幸いです

閾値(しきいち)とは、境界となる値。