HTML JavaScript TypeScript 技術ログ

【Intersection Observer API】Web開発者のためのパワフルな監視ツール

2023年5月30日

Intersection Observer APIは、「特定の部分までページをスクロールしたら任意の処理を実行したい」、「指定したページ要素が画面の下から表示されたら何か処理を実行したい」など、Webページを監視したいときに活躍します。

Web開発において、要素が画面内に表示されたかどうかを監視する必要がある場合があります。例えば、ユーザーが特定のセクションにスクロールした時に要素を表示したい場合や、画像や広告のレイジーローディングを実装したい場合などです。そこで登場するのが「Intersection Observer API」です。

本記事では、Intersection Observer APIについて詳しく解説し、その基本的な使い方や便利なユースケース、実際のコード例を紹介します。

Intersection Observer APIとは

Intersection Observer APIは、要素がビューポート(画面)内に表示されたかどうかを非同期に監視するためのJavaScriptのAPIです。従来の方法では、スクロールイベントやタイマーを利用して要素の可視性をチェックしていましたが、これは負荷が高くパフォーマンスに悪影響を及ぼす可能性がありました。

Intersection Observer APIは、これを改善し、効率的な監視機能を提供します。APIはブラウザ内部で要素の可視性を監視し、指定した条件に合致した場合にコールバック関数を実行します。

基本的な使い方

Intersection Observer APIを使用するには、以下のステップを実行します。

インスタンスを作成する

まず、Intersection Observerを作成する必要があります。以下のように、監視する要素とコールバック関数を指定します。

const observer = new IntersectionObserver(callback, options);
  • callbackは、要素が交差したときに実行されるコールバック関数です。
  • optionsは、オプションの設定です。例えば、交差のしきい値やルート要素などを指定できます。

監視を開始する

作成したIntersection Observerを使用して、監視を開始します。

observer.observe(target);
  • targetは、監視する要素です。

コールバック関数を処理する

要素が交差した場合に実行されるコールバック関数を定義します。

const callback = (entries, observer) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      // 要素が交差した時の処理
    } else {
      // 要素が交差から外れた時の処理
    }
  });
};
  • entriesは、交差した要素の情報を含む配列です。
  • isIntersectingプロパティは、要素が交差しているかどうかを示します。

以上がIntersection Observer APIの基本的な使い方です。次に、便利なユースケースを紹介します。

監視の停止

Intersection Observer APIでは、unobserve()メソッドを使用して監視を停止することもできます。これは、特定の要素が画面内に表示されなくなった場合や、要素が削除された場合に監視を停止するのに便利です。

以下は、監視を停止する例です。

const target = document.querySelector('.target-element');

const callback = (entries, observer) => {
  entries.forEach(entry => {
    if (!entry.isIntersecting) {
      observer.unobserve(entry.target);
    }
  });
};

const observer = new IntersectionObserver(callback);

observer.observe(target);

上記の例では、.target-elementという要素を監視しています。要素が画面内に表示されなくなると、コールバック関数内でunobserve()メソッドを使用して監視を停止します。

オプションの設定

Intersection Observer APIでは、オプションを設定することで監視の挙動をカスタマイズすることもできます。以下に一部のオプションを紹介します。

  • root: 監視する要素のルート要素を指定します。デフォルトはビューポートですが、他の要素を指定することもできます。
  • rootMargin: 監視範囲を拡大または縮小するマージンを指定します。マージンはCSSのmarginプロパティと同様の形式で指定します。
  • threshold: 交差の閾値を指定します。0から1の範囲の値を持ち、指定した値以上の交差率でコールバック関数が呼び出されます。

以下は、オプションの設定例です。

const options = {
  root: document.querySelector('.container'),
  rootMargin: '10px',
  threshold: 0.5
};

const callback = (entries, observer) => {
  // コールバック関数の処理
};

const observer = new IntersectionObserver(callback, options);

上記の例では、.containerという要素をルート要素として指定し、監視範囲を上下左右に10ピクセル拡大します。また、交差率が50%以上の場合にコールバック関数が呼び出されるように設定しています。

これらのオプションを使用することで、より詳細な監視の制御やカスタマイズが可能です。

ユースケース

いくつか、Intersection Observer APIのユースケースを紹介します。

複数の要素の監視

Intersection Observer APIは、複数の要素の監視にも利用することができます。例えば、画面内に表示された要素に対して特定のアニメーションを適用する場合などです。

以下は、複数の要素を監視する例です。

const elements = document.querySelectorAll('.target-element');

elements.forEach(target => {
  observer.observe(target);
});

上記の例では、.target-elementというクラスが付いた要素を全て監視しています。

動的なコンテンツの監視

動的なコンテンツ(例:Ajaxによるコンテンツの読み込み)の監視もIntersection Observer APIを使用して行うことができます。新しく追加された要素に対しても自動的に監視が適用されます。

以下は、動的なコンテンツの監視の例です。

const container = document.querySelector('.container');

const callback = (entries, observer) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      // 新しい要素が交差した時の処理
    }
  });
};

const observer = new IntersectionObserver(callback);

observer.observe(container);

上記の例では、.containerという要素を監視し、新しい要素が交差した場合に処理を行っています。

レイジーローディングの実装

Intersection Observer APIは、レイジーローディング(画像やコンテンツの遅延読み込み)の実装にも役立ちます。画面内に表示された要素に対して、実際に読み込む必要がある場合にのみリソースを読み込むことができます。

以下は、レイジーローディングの実装の例です。

const images = document.querySelectorAll('.lazy-image');

const callback = (entries, observer) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const image = entry.target;
      image.src = image.dataset.src;
      observer.unobserve(image);
    }
  });
};

const observer = new IntersectionObserver(callback);

images.forEach(image => {
  observer.observe(image);
});

上記の例では、.lazy-imageというクラスが付いた画像要素を監視し、画面内に表示された場合にdata-src属性の値をsrc属性にセットしています。

コード例

以下は、Intersection Observer APIを使用して要素の監視を行う基本的なコード例です。

const targets = document.querySelectorAll('.target-element');

const callback = (entries, observer) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      // 要素が交差した時の処理
    } else {
      // 要素が交差から外れた時の処理
    }
  });
};

const options = {
  root: null,
  rootMargin: '0px',
  threshold: 0.5
};

const observer = new IntersectionObserver(callback, options);

targets.forEach(target => {
  observer.observe(target);
});

上記の例では、.target-elementというクラスが付いた要素を監視し、要素が50%以上ビューポート内に表示された場合にコールバック関数が実行されます。

まとめ

本記事では、Intersection Observer APIについて解説しました。APIの基本的な使い方と共に、複数の要素の監視や動的なコンテンツの監視、レイジーローディングの実装についても紹介しました。Intersection Observer APIは、要素の可視性を効率的に監視します。これにより、動きのあるWebページを作成したり、表示速度を改善させたりすることができます。AppleのWebサイトでiPhoneの商品ページを見てみると、スクロールに応じていろいろな動きをすると思います。AppleのWebページがIntersection Observer APIを使用して実装されたものかは定かではありませんが、同じような動きのあるリッチなページをIntersection Observer APIを利用することで実装することができます。ぜひ、Appleのページを再現してみましょう。

付録:実装例

See the Pen test Intersection Observer API by Maita Tomoya (@mt114ran) on CodePen.

  • この記事を書いた人
  • 最新記事

Maita Tomoya / yone

2020.4~Webアプリケーションエンジニアとして都内の企業で働き、空いている時間でブログを運営している29歳男です。本ブログは情報の整理をするため、文章を書く機会を作るために始めました。1記事でも多く「誰かのためになる記事」を書けるように頑張ります!転職前は地方の高校で働いていました。教育関係の記事も定期的に書いていきたいと思います。

-HTML, JavaScript, TypeScript, 技術ログ