はじめに
フッターまでスクロールした際に、画面の下部にあるボタンがフェードアウトするような実装をしました。
scrollイベントだと、画面が動くたびにイベントが発火されるので、パフォーマンス的に良くないので、IntersectionObserverを使用しました。
IntersectionObserverについて
IntersectionObserverとは、指定した要素と基準要素が交差するのを非同期で監視してくれるという機能です。
IntersectionObserverは、別名 交差オブザーバー APIとも言います。
IntersectionObserverは、画面をスクロールした際にフェードインするようなアニメーションによく使われています。scrollイベントは、スクロールするたびにイベントが発火しますが、IntersectionObserverは非同期で実行されるのでパフォーマンスにも影響しにくいです。
IntersectionObserverの使い方
IntersectionObserverは、コンストラクターを呼び出し、指定した要素が基準とする要素を交差する度に実行されるコールバックを渡すことで生成することができます。
IntersectionObserverに、コールバック関数を設定します。
const observer = new IntersectionObserver(callback);
先ほど、IntersectionObserverに設定したコールバック関数を作成します。
コールバックの引数に IntersectionObserverEntry
オブジェクトの配列を受け取るので、forEach
で各要素に対して処理を行います。
またFooterのような要素が一つしかない場合は、entries[0]
で監視要素にアクセスすることができます。
const callback = (entries) => {
if (entries[0].isIntersecting) {
bottomListButton.classList.add("is-hidden");
} else {
bottomListButton.classList.remove("is-hidden");
}
};
次に、監視する要素、対象とする要素を指定します。
監視するDOM要素の取得方法は、querySelector
でもgetElementsByClassName
でも任意の方法で取得してください。
// 監視する要素
const $bottomListButton = document.querySelector('[data-target="jsBottomListButton"]');
// 基準にする要素
const footer = document.querySelector('[data-target="jsTargetFooter"]');
最後にオプションの設定を行います。
監視するDOM要素が、指定されたオプションを満たす度に、コールバック関数が実行されるようにオプションを設定します。
IntersectionObserver
のオプションは、以下のようなものがあります。
名前 | 内容 |
---|---|
root | 指定した要素と交差しているかを監視する要素。 初期値は、ビューポート(表されている画面)です。 |
rootMargin | rootの周りのマージンです。 値の指定方法は、"10px, 20px, 30px, 40px"(top, right, bottom, left)で設定することができます。 |
threshold | 指定した要素と、監視する要素がそれくらいの割合で交差すればコールバックを実行するかを指定することができます。交差する範囲が、50%を超えるときにコールバックを実行する際は、0.5と指定します。1.0と指定すると、全体が指定した要素と監視する要素の全てが交差すればコールバックが実行されます。 |
必要なオプションを設定してください。
const options = {
threshold: 1.0
}
オプションの設定ができましたら、IntersectionObserver
の第二引数にオプションを設定します。
observe()
メソッドに、監視する要素を指定すれば完成です。
const io = new IntersectionObserver(setIntersection, options);
io.observe($footer);
以下、全体のコードになります。
window.addEventListener('DOMContentLoaded', function() {
// 監視する要素
const bottomListButton = document.querySelector('[data-target="jsBottomListButton"]');
// 基準にする要素
const footer = document.querySelector('[data-target="jsTargetFooter"]');
//オプション
const options = {
threshold: 1.0
}
//コールバック関数
const callback = (entries) => {
if (entries[0].isIntersecting) {
bottomListButton.classList.add("is-hidden");
} else {
bottomListButton.classList.remove("is-hidden");
}
};
const io = new IntersectionObserver(callback, options);
io.observe(footer);
});
scrollイベントとIntersectionObserversの比較
以下の記事ですが、scrollイベントを使用した場合のパフォーマンスと、IntersectionObserversを使用した場合のパフォーマンスの比較を行った記事になります。
メインスレッドでスクリプト作業に費やした時間の割合を比較しています。
キャッシュなしの場合だと、scrollイベントとIntersectionObserversのパフォーマンスの差は、2倍以上IntersectionObserversの方が良いという結果がわかったそうです。
詳しくは、以下の記事をご覧ください。
参考記事