intersecton observer APIの解説記事

intersecton observer APIの解説記事

セサミ5

鍵のいらないスマートロック
セサミ5の体験談!オススメ商品!

スクロール監視の新定番 intersecton observer API

#181 スクロール監視

WEB制作

スクロールに応じて何を変更させたりするときに便利なintersecton Observer APIの解説記事です。 初めて聞くメソッドが多く、APIという名称が敷居を高く感じさせますが、使ってみると意外とシンプルで使い勝手のよい仕組みです。

公開日:
最終更新日:

商品リンクにアフィリエイト広告を利用しています

サイトマップサイトマップ

スクロール検知をもっと便利に Intersection Observer API

一定の位置までスクロールされたら、クラスを付与(または削除)する、という挙動を実装するには、従来の方法であれば、JavaScriptで位置の取得が必要でした。

JSでスクロールを取得するには、常に位置情報を監視し続ける必要があるので、負荷が気になるんですよね。

そんなときに便利なのがIntersection Observer API(交差セクションオブザーバーAPI)です。

Intersection Observer APIの概要

技術的な解説は以下のページが参考になります。
使い方の解説なども記載がありますので、一度目を通しておくと良いです。

読み込み中

Intersection Observer APIの役割は明確でわかりやすいんですが、コードは結構わかりづらいんですよね。

Intersection Observer APIを使う

このIntersection Observer APIを何に使うか。

私は仕事でLPを作るのですが、LPの下部に固定のCTA(コールトゥーアクション:申し込みボタンとか)を設置することを依頼されます。

その時にFV(ファーストビュー)を超えてから、固定ボタンを表示してほしい、と依頼を受けます。

ということで、それを想定してサンプルを作りたいと思います。
ちなみに似たようなものをこのページでも使用しています。

FVを超えたら固定CTAを表示する設計

必要な物が、CTAボタン、FV要素。

FVがページ上部に到達したら、固定CTAを表示するという仕様で作ります。

サンプルの挙動解説

FVと書かれた画像が、ウィンドウの上部に全部到達すると、CTAというボタンが表示されます。
Intersection Observer APIの「intersectionRatio」というプロパティを使うと、交差している量を計測できるのでそれを使っています。

このintersectionRatioの値が「0」になったらCTAボタンが表示されます。
intersectionRatioの値を「ページサンプル」という画像の下に表示するようにしています。

挙動サンプル

ファーストビュー
ページ要素

IntersectionRatio:

CTA

HTMLのサンプルコード

上記サンプルのHTMLコードです。

<div id="sample">
	<div id="fv">
		<img src="img/fv.png" width="640" height="960" loading="lazy">
	</div>
	<img src="img/page.png" width="640" height="250" loading="lazy">
	<p class="mt_20">IntersectionRatio:<span id="ir_value"></span></p>
	<div id="sample_cta">
		<img src="img/cta.png" width="640" height="117" loading="lazy">
	</div>
</div>		

サンプルのJavaScriptコード

上記サンプルのJavaScriptのコードを表示します。
ベースは先ほど紹介しているMDNをカスタマイズしたものです。

let target_item = document.querySelector("#fv");
let cta = 	document.querySelector("#sample_cta");
window.addEventListener("load", (event) => {
	sample_createObserver();	
}, false);

function sample_createObserver() {
	let sample_observer;
	let options = {
		root: null,
		rootMargin: "-70px",
		threshold: 0
	};
	sample_observer = new IntersectionObserver(cta_disp, options);
	sample_observer.observe(target_item);
}	

function cta_disp(entries){	
	entries.forEach(entry => {
		if (entry.intersectionRatio <= 0) {
			cta.classList.add("sample_on");
		}else{
			cta.classList.remove("sample_on");
		}				
	});
}	

サンプルコードの解説

実際に表示しているサンプルは、intersectionRatioの表示などもしているのですが、そこは省いて紹介します。

1.変数の定義

最初にFVとCTAの定義をしています。

let target_item = document.querySelector("#fv");
let cta = 	document.querySelector("#sample_cta");

2.実行関数の呼び出し

次にページが読み込まれたら、window.addEventListenerで、sample_createObserver()という関数を呼び出します。

window.addEventListener("load", (event) => {
	sample_createObserver();	
}, false);

3.sample_createObserverの定義

IntersectionObserverの呼び出しと、そのオプションの設定をしています。

function sample_createObserver() {
	let sample_observer;
	let options = {
		root: null,
		rootMargin: "-70px",
		threshold: 0
	};
	sample_observer = new IntersectionObserver(cta_disp, options);
	sample_observer.observe(target_item);
}	

let sample_observer;で定義した変数に、
new IntersectionObserver(cta_disp, options);を代入して、IntersectionObserverを呼び出す。

new IntersectionObserverの引数に入っている「cta_disp」は閾値を超えたら実行する関数が入っています。

4.optionsの内容

細かい設定はMDNの解説を一読することをオススメします。
が、わかりづらいので、私なりの解釈で説明入れておきます。

let options = {
	root: null,
	rootMargin: "-70px",
	threshold: 0
};

root: nullについて

これはスクロールする要素を指定します。
今回はnullを指定しているので、既定のブラウザのビューポートになります。

root
ターゲットが見えるかどうかを確認するためのビューポートとして使用される要素です。指定されなかった場合、または null の場合は既定でブラウザーのビューポートが使用されます。

MDNより引用

rootオプションを指定した場合、監視対象はrootの子要素でなければ動作しません。

null以外の指定方法

nullではなく、要素を指定する場合は、

root: document.querySelector("#fv"),

のように指定します。

rootMargin: "-70px",について

これは、交差地点のマージンを指定しています。
私のサイト(今見ているページ)には、ページ上部に固定のナビが入っているので、その分を抜いて計算させています。

-(マイナス)の値を入れると交差地点が下に下がります。

threshold: 0 について

対象の要素がどの程度表示されたらコールバックをさせるか、を指定する値になります。

もしかしたら間違っているかもですが、IntersectionRatioの値と同じと考えてよいかと思います。

「intersectionRatio」は前述しましたが、交差地点と監視対象がどの程度、交差しているかを測るプロパティです。

「intersectionRatio」が「0」になったら、「cta_disp」関数が呼び出されるという仕組みです。

サンプルでは、intersectionRatioの値を表示しているので参考にしてください。
交差が開始すると「1」以下の数値になり、交差し終わると「0」になります。

threshold:は複数指定できる

thresholdは複数個の値を指定できます。
複数個を指定する場合は、配列の書式で記述します。

threshold: [0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1]

このページで実際に表示しているサンプルは、0~1までを0.1で区切ってコールバックしています。

intersectionRatioを細かく表示するために、このようにしていると。

threshold:0 は完全にスクロールしたら発動

この「threshold」の値が「0」というのは、言い換えると「見えなくなったら発動」ということになります。

0の場合、完全にスクロールして見なくなったらコールバックが発動する、という意味です。

逆に「1」を指定すると、対象要素が完全に表示されている(1pxもスクロールエリアにかかっていない)状態で発動となります。

サンプルの場合、FVがスクロールし終わったらCTAを表示する、という目的なので「0」を指定しているというわけですね。

5.sample_observerの定義

解説が長くなったのでコードを再掲します。
8行目の「sample_observer = new IntersectionObserver(cta_disp, options);」の解説です。

function sample_createObserver() {
	let sample_observer;
	let options = {
		root: null,
		rootMargin: "-70px",
		threshold: 0
	};
	sample_observer = new IntersectionObserver(cta_disp, options);
	sample_observer.observe(target_item);
}	

new IntersectionObserver(cta_disp, options);で、「IntersectionObserver」を呼び出し、その引数で「cta_disp」関数と、「options」を指定します。

コールバックで呼び出す関数を指定する、と、オプションを指定する、と覚えればOK。

6.監視対象の指定

9行目の、sample_observer.observe(target_item); は、スクロールを監視する対象を指定します。

target_itemは以下のものを指定しています。

let target_item = document.querySelector("#fv");

「#fv」がスクロールの監視対象になっています。

7.コールバックする関数の解説

いよいよ最後の関数です。
コールバックされたときに実行する関数です。

function cta_disp(entries){	
	entries.forEach(entry => {
		if (entry.intersectionRatio <= 0) {
			cta.classList.add("sample_on");
		}else{
			cta.classList.remove("sample_on");
		}				
	});
}

function cta_disp(entries)の引数の「entries」の中身は「IntersectionObserverEntry」のオブジェクトの配列が入ります。

この内容を知りたい場合はconsole.logで表示させると確認できます。
色々な値が入っております。

entries配列の中身の一部

以下が実際に「entries」をconsole.logで表示させた配列の内容の一部です。

[IntersectionObserverEntry]
0: IntersectionObserverEntry
boundingClientRect: DOMRectReadOnly {x: 111.5, y: -1262.0625, width: 840, height: 990, top: -1262.0625, …}
intersectionRatio: 0
intersectionRect: DOMRectReadOnly {x: 0, y: 0, width: 0, height: 0, top: 0, …}
isIntersecting: false
isVisible: false
rootBounds: DOMRectReadOnly {x: 70, y: 70, width: 1283, height: 1424, top: 70, …}
target: div#fv
time: 280.2000000178814
[[Prototype]]: IntersectionObserverEntry
length: 1
[[Prototype]]: Array(0)

entries配列をforEachで展開して条件指定

entriesが配列なので、forEachで展開し、その配列の中にある「entry.intersectionRatio」の値に対してif文を指定。

if (entry.intersectionRatio <= 0) {
	cta.classList.add("sample_on");
}else{
	cta.classList.remove("sample_on");
}			

intersectionRatioの値が「0」以下の場合「sample_on」というCSSのクラスを付与し、0より大きい場合はそのクラスを削除しています。

▼指定しているCSSの内容はこちら。

#sample_cta{
	visibility: hidden;
}

#sample_cta.sample_on{
	visibility: visible;
}

サンプルはCLSの発生が嫌だったので、visibilityで非表示化しています。

intersectionRatioの値が「0」以下なので、FV要素がページ内から完全にスクロールし終わったら、CTAが表示される、という仕組みですね。

Intersection Observer APIまとめ

ちゃんと理解して使おうとするとなかなかややこしいのですが、コード自体は短めで構造はシンプルなので使いやすいと思います。

私もちゃんとは理解してないのですが、この記事を書いて少し理解が深まりました。

常に監視し続けなくて良いのがメリットで、ユーザーの環境に負荷がかからず良いとおもいます。

使い方次第でいろいろと使い道がありそうなので、ぜひ使ってみてください。

主にrootMarginについて追記しました

rootMarginの考え方を中心に、スクロールに応じて画像が大きくなるサンプルを使った解説記事を追加しました。

WEBデザイナー・プログラミング学習にオススメ

記事内で紹介している商品リスト
(価格はAmazon参考価格)

独習JavaScript 新版

Amazon SALE中
¥3,278 10%OFF 328円OFF

2,950円(税込)

独習JavaScript 新版

JavaScript 第7版

5,060円(税込)

JavaScript 第7版

いちばんやさしいJavaScriptの教本 第2版 ECMAScript 2017(ES8)対応 人気講師が教えるWebプログラミング入門 「いちばんやさしい教本」シリーズ

Amazon SALE中
¥2,420 10%OFF 242円OFF

2,178円(税込)

いちばんやさしいJavaScriptの教本 第2版 ECMAScript 2017(ES8)対応 人気講師が教えるWebプログラミング入門 「いちばんやさしい教本」シリーズ

図解! JavaScriptのツボとコツがゼッタイにわかる本 “超”入門編

2,138円(税込)

図解! JavaScriptのツボとコツがゼッタイにわかる本 “超”入門編

JavaScript コードレシピ集

Amazon SALE中
¥3,278 2%OFF 66円OFF

3,212円(税込)

JavaScript コードレシピ集

JavaScript[完全]入門

Amazon SALE中
¥2,948 10%OFF 295円OFF

2,653円(税込)

JavaScript[完全]入門

ステップアップJavaScript フロントエンド開発の初級から中級へ進むために

Amazon SALE中
¥2,640 10%OFF 264円OFF

2,376円(税込)

ステップアップJavaScript フロントエンド開発の初級から中級へ進むために

スクロール監視の関連ページ

SNSでこの記事をシェアできます

ブログ デイリーアクセスランキング

ホワイトボード
1位

ホワイトボード

100均で買えるつっぱり棒とネットを使ってホワイトボードを窓枠に設置してみました。 ホーロー製のホワイトボードがオススメ!

MusicBeeのレイアウト変更方法
2位

MusicBeeのレイアウト変更方法

MusicBee 3.1のレイアウトをデフォルトの状態から、自分好みのレイアウト設定に変更する方法を写真付きで紹介しています。

セサミ5とセサミタッチ
3位

セサミ5とセサミタッチ

CANDY HOUSEのセサミ5とセサミタッチの導入レビューです! 指紋認証とNFCタッチで鍵いらずな生活を手に入れました!

セサミタッチで使えるICタグ
4位

セサミタッチで使えるICタグ

セサミ5とセサミタッチを購入して1ヵ月。子供の指紋認証が通りづらいという問題が発生したので、NFCタグを購入して追加設定しました。

株式会社とは
5位

株式会社とは

株式投資を初めて、株式会社の仕組みと株式と株価と資本金などの関係性が良くわかっておらず、ちょっと調べてみました。

Kazakiri カミソリレビュー
6位

Kazakiri カミソリレビュー

カミソリの替刃の価格が高すぎるので1枚当たり11円で使える片刃のカミソリを購入しました! DORCOの替刃がオトク!

SOUNDPEATS Air5 Pro
7位

SOUNDPEATS Air5 Pro

SOUNDEPETAS史上最高のノイズキャンセルを搭載した最新のAir5 Proのレビューです! コーデックが大幅に強化!

湯楽城
8位

湯楽城

2024年8月に千葉県は成田に1泊2日の旅に行ってきました! お目当ては総工費24億円をかえて建設された「湯楽城」へ

運動会
9位

運動会

子供の運動会にα7Ⅲで初参戦!望遠レンズを買おうか迷ったのですが、本体とセットのズームレンズ1本で運動会を撮影してきました。

Mx Master4
10位

Mx Master4

2025年10月30日発売のロジクールMX Master4のレビュー! 歴代のMXシリーズの中でも最高傑作の逸品です!

カテゴリ一覧

オススメ商品レビュー

オススメ商品レビュー

世の中にある比較サイトや、いかがでしたか系サイトが嫌いなんです。使ってないのにえらそうなこと言うなと。なので体験談です。

WEB制作

WEB制作

WEBサイトを作れますと一言に言っても色々な技術があるわけですよ。アウトプットの形は一緒でもいろいろこだわりがあるんです。

カメラ

カメラ

2018年4月に購入したソニーのミラーレス一眼「α7Ⅲ」に関連する記事一覧ページです。 作例集やカメラグッズレビューなど。

美味しいもの

美味しいもの

食に関してはあまりこだわりがないんですけどね、こだわりがない分美味しいと思ったものは本当においしいと思ったものなんですよ

Amazonプライム動画

Amazonプライム動画

Amazonプライム会員なら無料で利用できるAmazonプライム動画から、いろいろな動画をみたレビュー記事のまとめページ

旅LOG

旅LOG

家族旅行やおでかけした際の旅ブログです。夏休みの家族旅行(4人家族)で訪れた観光名所の感想などを記しています。

プロフィール

プロフィール

Start-Point.netの管理人のプロフィール紹介を兼ねた、自分の中のルールや決め事やエピソードなでお書いていきます

日記

日記

日記と言っても色々な日記があるわけで、記録的な日記や心理描写を色濃く描いた日記などをまとめたページです。

thanks

thanks

自分を表現することって意外と難しいんですよね。照れがあったり、間違ったこといってないかとよくわからない何かと戦ったりして。

マネーリテラシー

マネーリテラシー

お金や税金、資産形成に関する情報や体験談をブログでお伝え!

記事内で紹介している商品

独習JavaScript 新版

2,950
(税込)