【JavaScript】IntersectionObserverを使って複数要素にスクロールイベントを設定する方法

IntersectionObserver を使用することで、ウェブページのスクロールイベントに応じて要素の表示状態を簡単に管理できます。複数の要素が画面に現れたり消えたりするタイミングでアクションを実行する方法について詳しく解説します。

IntersectionObserverの基本

IntersectionObserver は、要素がビューポート(画面に表示される領域)に入るかどうかを監視するためのインターフェースです。要素が指定した条件を満たしたときに、コールバック関数が実行されます。

// コールバック関数を定義
const callback = (entries, observer) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      // 要素がビューポートに表示されている時の処理
      entry.target.classList.add('visible');
    } else {
      // 要素がビューポートから外れた時の処理
      entry.target.classList.remove('visible');
    }
  });
};

// IntersectionObserverのオプションを設定
const options = {
  root: null, // ビューポートを監視対象のルートに設定
  rootMargin: '0px', // ビューポートに対するマージン
  threshold: 0.5 // 要素がビューポートの50%に表示されるときにトリガー
};

// IntersectionObserverをインスタンス化
const observer = new IntersectionObserver(callback, options);

複数要素の監視

IntersectionObserver を使って複数の要素を監視するのは非常に簡単です。監視したい要素を選択し、それぞれに対して observe メソッドを呼び出します。

以下の例では、クラス .watch を持つ全ての要素を監視します。

// 監視したい要素を取得
const elements = document.querySelectorAll('.watch');

// 各要素に対してobserveメソッドを呼び出す
elements.forEach(element => {
  observer.observe(element);
});

完全な実装例

以下は、IntersectionObserver を使って複数の要素がビューポートに入ると背景色が変わる完全な例です。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>IntersectionObserver Example</title>
  <style>
    .item {
      height: 200px;
      margin: 50px;
      background: lightblue;
    }
    .visible {
      background: lightcoral;
    }
  </style>
</head>
<body>
  <div class="item">Item 1</div>
  <div class="item">Item 2</div>
  <div class="item">Item 3</div>
  <div class="item">Item 4</div>
  <div class="item">Item 5</div>
  
  <script>
    const callback = (entries, observer) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          entry.target.classList.add('visible');
        } else {
          entry.target.classList.remove('visible');
        }
      });
    };

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

    const observer = new IntersectionObserver(callback, options);
    
    const elements = document.querySelectorAll('.item');
    elements.forEach(element => {
      observer.observe(element);
    });
  </script>
</body>
</html>

このコードでは、.item クラスが付けられた複数の要素がビューポートに表示されると、その背景色が変更されます。IntersectionObserver により、要素が画面に現れたときのスタイル変更を簡単に管理できます。