IntersectionObserverで実現する「要素が見えたら◯◯する」の処理!

2025年5月13日火曜日

HTML javascript

t f B! P L

IntersectionObserverとは?

IntersectionObserver は、ある要素(ターゲット)が ビューポート または指定した親要素(ルート)と交差した瞬間を非同期に検知できるブラウザ API です。従来のスクロールイベント監視よりも高パフォーマンスで、実装量も少なく済むため、下記のような場面でよく利用されます。

ユースケース 目的
遅延画像読み込み(Lazy Loading) 画像が表示領域に入ったときだけ src を設定します
無限スクロール 番兵要素が交差したら次のページを取得します
スクロールアニメーション 要素が現れた瞬間に CSS クラスを付与します
広告・アナリティクス計測 ビューアブルインプレッションを計測します

仕組み

  1. Observer を生成します

    const observer = new IntersectionObserver(callback, options);
    
    • callback は交差状態が変化したときに呼び出されます

    • options では root, rootMargin, threshold などを設定できます

  2. 監視を開始します

    observer.observe(targetElement);
    
  3. 交差判定のたびに callback が実行されます
    callbackIntersectionObserverEntry の配列を受け取り、isIntersecting(交差しているか)や intersectionRatio(交差率)などを参照できます。

  4. 不要になったら監視を解除します

    observer.unobserve(targetElement); // 個別に解除
    observer.disconnect();             // まとめて解除
    

サンプルコードで使い方を解説

以下のコードでは、左側のスクロールボックスを上下に動かすと、赤い .target 要素の表示/非表示に合わせて右側のメッセージが更新されます。

<script>
window.addEventListener("DOMContentLoaded", () => {
  // 1. Observer インスタンスを生成します
  const intersectionObserver = new IntersectionObserver((entries) => {
    // 3. 交差判定後にコールバックが呼び出されます
    if (entries[0].isIntersecting) {
      document.querySelector(".message span").innerText = "表示された";
    } else {
      document.querySelector(".message span").innerText = "非表示です";
    }
  });

  // 2. 監視を開始します
  const target = document.querySelector(".target");
  intersectionObserver.observe(target);
});
</script>
説明
1 IntersectionObserver を生成します。options を省略すると root はビューポート、threshold0 になります。
2 observe() に対象要素を渡して監視を開始します。複数要素を監視したい場合は observe() を繰り返します。
3 entries は配列で届きます。ここでは 1 要素のみ監視しているため entries[0] を直接参照しています。isIntersectingtrue なら要素は表示中と判断し、メッセージを更新しています。

ポイント

  • 同じ要素でも交差状態が変わるたびにコールバックが再実行されます

  • 交差率を細かく制御したい場合は threshold に配列(例: [0, 0.5, 1])を指定します

オプションを加えた拡張例

次の例では 50%以上表示されたら発火 し、一度だけ処理を実行したあと監視を解除します。

const onceObserver = new IntersectionObserver(
  (entries, observer) => {
    entries.forEach((entry) => {
      if (entry.intersectionRatio >= 0.5) {
        entry.target.classList.add("visible");
        observer.unobserve(entry.target); // 一度きりで監視解除
      }
    });
  },
  {
    root: document.querySelector(".scroll-container"), // 親要素基準で判定します
    rootMargin: "0px",
    threshold: 0.5
  }
);

document.querySelectorAll(".item").forEach((el) => onceObserver.observe(el));
option 意味
root null(既定)ならビューポートを基準にします。要素を指定するとその要素内のスクロールを基準に判定します。
rootMargin CSS の margin と同じ書式で判定領域を拡張または縮小します(例: "0px 0px -20% 0px")。
threshold 交差率を 0~1 で指定します。配列を渡すと複数ポイントで判定が行われます。

まとめ

  • IntersectionObserver はスクロール連動処理の定番 API で、ブラウザに最適化された非同期処理により高いパフォーマンスを発揮します。

  • 実装は Observer 生成 → 対象を observe() → コールバックで処理 のシンプルな 3 ステップです。

  • rootrootMarginthreshold を組み合わせることで、遅延読み込みや無限スクロール、スクロールアニメーションなど幅広い用途に応用できます。

  • 監視解除 (unobserve または disconnect) を忘れないことで、不要なコールバックやメモリリークを防止できます。

ぜひご自身の Web アプリに IntersectionObserver を取り入れて、軽快なスクロール体験を実現してください。

スポンサーリンク
スポンサーリンク

このブログを検索

Profile

自分の写真
Webアプリエンジニア。 日々新しい技術を追い求めてブログでアウトプットしています。
プロフィール画像は、猫村ゆゆこ様に書いてもらいました。

仕事募集もしていたり、していなかったり。

QooQ