従来、スクロールに合わせて要素を操るには scroll
というイベントを利用していました。ただ、それだと画面サイズが変わったら再計算しないといけなかったり、スクロールするたびに関数を呼び出すので、パフォーマンスへの悪影響が懸念されていました。
それを解決するが本日紹介するIntersectionObserver
です。
IntersectionObserverとは、Intersection:交差 , Observer:観察者
という意味があります。つまり、特定の要素が指定領域内に入ったかどうかを検知するAPIのことです。なので、スクロールイベント等を実装するときに使用するAPIです。
https://developer.mozilla.org/ja/docs/Web/API/IntersectionObserverAPI
基本的には IntersectionObserver
を呼び出して、第1引数に実行したい関数、第2引数にオプション設定を記述します
const options = {
root: document.querySelector('#scrollArea'),
rootMargin: '0px',
threshold: [0.2, 1.0]
}
const observer = new IntersectionObserver(callback, options);
options
オブジェクトは、以下のフィールドがあります:
ターゲットとなる要素が見えるかどうかを判定するためのベース部分を指定します。デフォルトはブラウザのビューポートです。
交差を計算する際は、実際は基準要素の領域にここで指定した余白値を足した領域が計算基準となる。つまり例えばここに正の値を指定すれば、実際に見える前に交差していると判定させることができる。デフォルトは 0px
です。
関数を実行するタイミングを 0〜1 の間で記述します。コールバックを実行する交差の閾値リスト。交差の割合が閾値を上回るか下回ったときのみコールバック関数が実行される。[0, 0.5, 1]
のように配列形式でも記述できます。上の例でいうと、見えている割合が20%および100%を上回るか下回ったときにコールバックが実行される。デフォルトでは0
です。
では、実際に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;
}
最後までお読みいただきありがとうございました。
参考になれば幸いです
※閾値(しきいち)とは、境界となる値。