ホームページ制作のご依頼・ご相談はCOLERSへ

【JavaScript】スクロールで発火するイベントをGoogleが遅延読み込みで推奨するIntersection Observer APIで実装

  • HTML
  • CSS
  • JS

動きのあるWEBデザインのアニメーションとして、
該当の要素まで「スクロールすると発火するイベント」はよく利用されます。

また、パフォーマンスの観点で画像の遅延読み込み(lazy-load)を行う場合も同様です。

今回はGooglebotも認識ができGoogle検索で推奨しているIntersection Observer APIを利用して
スクロールで発火するイベント(コンテンツの遅延読み込み)を実装する方法をご紹介します。

目次

実装した結果

Intersection Observer APIを利用したスクロールイベントをデモページで確認する

実際のコードと解説

HTML、CSS、およびJavaScriptのそれぞれのコードは以下のとおりです。

HTML

フェードインのためのサンプル要素になります。
監視対象の目印としてanimation-fadeという名称でクラスを付与しています。

<div class="box animation-fade">
  <p>フェードイン</p>
</div>
<div class="box animation-fade">
  <p>フェードイン</p>
</div>
<div class="box animation-fade">
  <p>フェードイン</p>
</div>
<div class="box animation-fade">
  <p>フェードイン</p>
</div>

CSS

Sassの環境がない方も利用できるようにCSSでご紹介します。

サンプルのための標準スタイルとアニメーションはCSSで定義しています。
スクロールして条件が整った場合にはJavaScriptでactiveクラスを付与し、
フェードインするアニメーションが実行されるようにしています。

/* サンプルのための標準のスタイル
-----------------------------------------*/
.box {
  height: 500px;
  padding: 1em;
  margin: 0;
  background-color: #f7f7f7;
}
.box:nth-of-type(even) {
  background-color: #212121;
  color: #fff;
}
p {
  margin: 0;
  font-size: 24px;
  font-weight: bold;
  letter-spacing: 1px
}

/* サンプルのためのアニメーション
-----------------------------------------*/
.animation-fade {
  opacity: 0;
}
.animation-fade.active {
  animation: fadein 1s ease-in-out forwards;
}
@keyframes fadein{
	0%{
		opacity: 0;
		transform: translateX(20px);
	}
	50% {
		opacity: 0;
		transform: translateX(20px);
	}
	100%{
		opacity: 1;
		transform: translateX(0);
	}
}

JavaScript

解説はコードのコメントで記載していますが、
Intersection Observer APIを利用して監視対象を登録し、
オプション、スクロール後に実行される関数を引数として渡しています。

サンプルはブラウザのビューポートの中央に対象要素が交差した瞬間、
対象要素へactiveクラスを付与するという内容で実装しました。

その後、active要素に対してCSSでアニメーションを実行します。

// 対象となる要素をすべて変数へ格納
const fadeTargets = document.querySelectorAll(".animation-fade");

// オプション
// root : nullの場合はブラウザのビューポート
// rootMargin : 0とすると↑で指定したルート要素と交差した瞬間(1pxでも)発火。今回のように-50%とすると対象要素がルート要素であるブラウザのビューポートの半分のところで交差したら発火となる。ルート要素を基準としたオプション。
// threshold : 閾値(しきいち)。どのくらい交差したら発火するかを指定する。0とすれば交差した瞬間に発火。対象要素を基準としたオプション。
// rootMarginとthresholdで交差してから(可視範囲に入ってから)どの程度で発火するかを調整できるということ。
const fadeOption = {
  root: null,
  rootMargin: "-50% 0px",
  threshold: 0
};

// 対象となるターゲットが可視範囲に入ったらactiveというクラスを付与する関数
const targets = (entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      entry.target.classList.add("active");
    }
  });
};

// 可視範囲に入ったら実行する関数targetsとfadeOptionを引数にしてIntersectionObserverコンストラクターを呼び出し
const fadeObserver = new IntersectionObserver(targets, fadeOption);

// fadeTargetsのすべての要素を監視印象に登録
fadeTargets.forEach((target) => {
  fadeObserver.observe(target);
});

最後に

ポイントとなる要素のアニメーションで動きをつけることは
ユーザー体験においても重要です。

様々用意されたライブラリを利用する方法もありますが、
今回はIntersection Observer APIを用いてかんたんに実装する方法をご紹介しました。

値を調整することで応用も可能ですし、アニメーション内容についてはCSSで定義していますので、
ご自身のプロジェクトにあわせて調整いただければ幸いです。

  1. SNIPPET
  2. JavaScript
  3. 【JavaScript】スクロールで発火するイベントをGoogleが遅延読み込みで推奨するIntersection Observer APIで実装