【Webページ監視用API】Intersection Observerとは

今回は前回のブログの続きで、Intersection Observerのご紹介をしたいと思います。

Intersection Observerを使うことで、従来までの面倒くさいscrollイベントを使わずに、特定の位置でイベントを管理することができます。

ぜひ、このブログでIntersection Observerについて少しでもご理解いただけると嬉しいです!

Intersection Observerとは?

Intersection Observerは直訳すると交差点の観測者という意味になります。
この観測者はページ内の要素と要素の交差を検知するAPIになります。

つまり、従来のscroll/resizeイベントを使った監視方法とは異なり、ここではビューポートサイズが要素に交差したかどうかを監視するため、スクロール量と関係なく実装することがでるので、パフォーマンスの向上につながります。また、レスポンシブにも対応しているため、レスポンシブ用の関数を別に用意する必要がないのもいい点です。

このIntersection Observerを用いた方法は、googleでも推奨されています。その理由として、WEBサイトの診断を行うgoogleロボットはそもそもスクールをしないというのがあります。そのため、従来のスクロールイベントで発火する仕組みでは、ロボットには検知できない可能性があります。今後のアップデートで改善される可能性はありますが、現段階では、スクールイベントで管理しているJSライブラリは要注意ですね!

Intersection Observerの設定

const options = {
    root: document.querySelector('.root'),
    rootMargin: "100px 20px",
    threshold: [0, 0.5, 1.0]
};

Rootは、ターゲットと交差する枠のようなものです。(ルート要素)rootを変更することで指定した要素がターゲットと交差した際の動作を指定することができます。デフォルトでは、ビューポートが指定されおり、ユーザーが見ている画面が有効になっています。

rootMarginはその名の通り、root要素に対して交差を検知する位置を設定することができます。「マイナス値」を設定するとルート要素の手前で交差を検知します。設定方法はcssのpaddingやmarginなどの設定と同じです。

Thresholdは交差を検知する閾値で、0~1の値を設定することができます。デフォルト0の場合は交差領域が0、つまり重なり始めと重なり終わりに検知されます。

使ってみよう!

  • white
  • red
  • blue
  • green
  • yellow

百聞は一見にしかず!まずは実際にどう動くのか試してみましょう!

手順としては、まず監視するターゲットを指定して、Intersection Observerを設定します。次に、Intersection Observerが検知した際のコールバック関数を呼び、実際にコールバック関数で要素が交差した際の処理を実行するだけです。従来のようなscrollイベントやフラグ処理はいりません。

<div class="sample_box">
  <header id="header">header</header>
  <section class="list_section">
    <ul>
      <li class="box" id="white">white</li>
      <li class="box" id="red" style="color: red">red</li>
      <li class="box" id="blue" style="color: blue">blue</li>
      <li class="box" id="green" style="color: green">green</li>
      <li class="box" id="yellow" style="color: yellow">yellow</li>
    </ul>
  </section>
</div>
.sample_box {
  position: relative;
  width: 100%;
  height: 400px;
  overflow: hidden;
}
.sample_box header {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100px;
  padding: 30px 0;
  text-align: center;
  z-index: 100;
}
header.white {
  background-color: white;
}
header.red {
  background-color: red;
}
header.blue {
  background-color: blue;
}
header.green {
  background-color: green;
}
header.yellow {
  background-color: yellow;
}
.list_section{
  width: 100%;
  height: 600px;
  overflow-y: auto;
}
.sample_box ul {
  width: 100%;
  height: auto;
  padding: 200px 0 400px;
}
.sample_box li {
  width: 100%;
  height: 100px;
  padding: 0;
  text-align: center;
}
      // 交差を監視する対象の要素
      const boxes = document.querySelectorAll(".box");
      const newHeader = document.getElementById("header");

      const options = {
        root: document.querySelector('.sample_box'), 
        rootMargin: "-50% 0px",
        threshold: 0,
      };
      const observer = new IntersectionObserver(callback, options);
      // それぞれのboxを監視する
      boxes.forEach((box) => {
        observer.observe(box);
      });

      /**
       * 交差したときに呼び出す関数
       */
      function callback(entries) {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            activateIndex(entry.target);
          }
        });
      }

      /**
       * ヘッダーの色を変える関数
       */
      function activateIndex(element) {
        // 引数で渡されたDOMのの色をheaderクラスに指定
        newHeader.className = element.id;
      }

まとめ

今回はIntersection Observerをご紹介しました。メリットをまとめると

  • Googleロボットでも検知できる
  • レスポンシブにも対応
  • パフォーマンスも向上
  • Scrollイベントなどでスクロールを計算しなくていい
  • 複数の要素でも簡単に実装できる

いいこと尽くしですね!現在はスクロールでイベントを管理する際は、Intersection Observer一択感があります。前回ご紹介した画像の遅延読み込みでも例外ではなく、Intersection Observerを用いるのが主流になっています。それ用のJSライブラリもありますので、今度記事でご紹介したいと思います。