Intersection Observer APIを図解で解説

Intersection Observer APIを図解で解説

Intersection Observer APIを図解で解説

#195 交差監視

WEB制作

Intersection Observerを仕事で使ったときにイマイチ理解度が足りないと感じ、もっとわかりやすい解説記事を書きました。 サンプルにスクロールに応じて画像が拡大するモーションを作りました。 rootMarginの使い方を詳しく。

公開日:
最終更新日:

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

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

Intersection Observer APIをもっとわかりやすく解説したい

インターセクションオブザーバーという、交差監視のJavascriptの解説記事を書いたのですが、自分で読み返してもイマイチわかりづらいので、もっとわかりやすく解説記事を書きたいと思います。(自分用)

前回のIntersection Observer APIの解説記事はこちらです。
コードの解説にフォーカスしすぎて、概念というか、考え方のようなものがすっぽり抜けているんですよね。

Intersection Observer APIの動作の仕組みや、基本的な使い方などは、上述した記事で解説しているので、まだ未読の方は一読をオススメします。

今回のゴールはこの動作を作ります

縦に並べられた写真が、スクロールすると大きくなる、という動作を設定します。

  • Intersection Observer サンプル
  • Intersection Observer サンプル
  • Intersection Observer サンプル
  • Intersection Observer サンプル
  • Intersection Observer サンプル
  • Intersection Observer サンプル
  • Intersection Observer サンプル
  • Intersection Observer サンプル

鳥の写真は静岡県にあるシャボテン公園で撮影したもの。

サンプルでやってること

Intersection Observerを使って、ビューポートの50%に入ったら、「sample_on」というクラスを付与し、外れたら外す、という動作をしています。
画像の拡大は付与された「sample_on」クラスがになっております。

やってることはいたってシンプル。

サンプルのHTMLコード

ulとliで画像をならべているだけです。
ulのIDにinter_ulを指定。

<ul id="inter_ul">
	<li><img src="img/A7306414.jpg" width="760" height="760"></li>
	<li><img src="img/A7306532.jpg" width="760" height="760"></li>
	<li><img src="img/A7306550.jpg" width="760" height="760"></li>
	<li><img src="img/A7306739.jpg" width="760" height="760"></li>
	<li><img src="img/A7306740.jpg" width="760" height="760"></li>
	<li><img src="img/A7306763.jpg" width="760" height="760"></li>
	<li><img src="img/A7306880.jpg" width="760" height="760"></li>
	<li><img src="img/A7306893.jpg" width="760" height="760"></li>
</ul>

サンプルのCSSコード

こちらもおもにレイアウト用のスタイルになっています。

#inter_ul {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    margin: 20px auto;
}
#inter_ul li {
    list-style: none;
    width: 70%;
    text-align: center;
    transition: all 0.5s 0s ease;
}

/* ▼画像拡大用 */
#inter_ul li.sample_on {
    width: 100%;
}

画像の大きさはliのwidthを拡大することで表現しており、liのCSSに「transition: all 0.5s 0s ease;」を設定してアニメーション効果を出しています。

サンプルのjavascriptコード

このjavascriptの役割は、スクロールに応じてクラスを付与、削除する、という役割です。

<script>
//①ターゲット
const target_item = document.querySelectorAll("#inter_ul li");
	
//②関数の呼び出し	
window.addEventListener("load", (event) => {
	//③の関数をここで呼び出し
	createObserver();	
}, false);

//③呼び出される関数
function createObserver() {
	let options = {
		root: null,
		rootMargin: "-50% 0px",				
		threshold: 0
	};
	let main_observer;
	main_observer = new IntersectionObserver(photo_set, options);
	target_item.forEach( (elem) => {
		main_observer.observe(elem);
	}); 
}	

//④交差時のアクション
function photo_set(entries){	
	entries.forEach(entry => {				
		if (entry.isIntersecting) {
			entry.target.classList.add("sample_on");
		}else{
			entry.target.classList.remove("sample_on");
		}					
	});
}	
</script>

Intersection Observerに必要な物

サンプルを提示したところで、ここから解説パートに入りたいと思います。

Intersection Observerは交差監視なので、交差するもの(ターゲット)と、交差地点があります。
そして、交差した場合にさせる処理の3つから成り立っています。

ターゲットとは

今回のサンプルの交差するもの「ターゲット」は「li」タグになります。
正確には「#inter_ul」IDの子要素の「li」タグ全てです。

このターゲットは、もちろんliタグ以外も使えます。
javascriptで指定できるDOM要素であれば、なんでもOK。(多分)

前回の例では、ファーストビューの画像がターゲットでした。
今回は複数ターゲットの事例で紹介しています。

ターゲットはli
//①ターゲット
const target_item = document.querySelectorAll("#inter_ul li");

↑javascriptのコードでいうとこれ。

このターゲット要素が交差エリアに入ったら、クラスを付与するわけですね。

交差エリアについて rootMargin

rootMarginの考え方が結構わかりづらく、色々実験してようやく把握できました。

//③呼び出される関数
function createObserver() {
	let options = {
		root: null,
		rootMargin: "-50% 0px",				
		threshold: 0
	};
	let main_observer;
	main_observer = new IntersectionObserver(photo_set, options);
	target_item.forEach( (elem) => {
		main_observer.observe(elem);
	});
}

↑このコードの5行目、optionsの中にあるrootMarginです。

rootMarginの書き方について

rootMarginには必ず、px か % をつける必要があります。0でも0pxとする必要があります。

この「値」は上・右・下・左の4個所を指定できます。
CSSと同じ形式でショートハンドでも記述が可能です。

-(マイナス)のネガティブマージンの指定もできます。
但し、vwやvh、remなどは使えません。単位は「px」or「%」 です。

サンプルでやってる-50%について

サンプルでは上下に対して-50%を指定しています。
簡単に一言で言うと、表示エリアの上下から真ん中を指定しています。

rootMargin-50%をより詳しく解説

rootMargin:-50%を図解にするとこうなります。

rootMargin-50%

上下から-50%とっているので、ちょうど真ん中に一本の線が引かれた交差地点になります。

サンプルは大きさを変更しているのでちょっとわかりづらいのですが、注意してみるとビューポートの真ん中を超えると発動しているのがわかります。

発動条件の確認

ターゲットアイテムが交差地点に入ったら、sample_onクラスが付与され、画像が拡大します。

Intersection Observerの発動条件

これはターゲット要素の上端が入った時点で発動します。
※発動条件によりますが今回のサンプルは。

//④交差時のアクション
function photo_set(entries){	
	entries.forEach(entry => {				
		if (entry.isIntersecting) {
			entry.target.classList.add("sample_on");
		}else{
			entry.target.classList.remove("sample_on");
		}					
	});
}

今回のサンプルのクラス付与の条件は、
上記コードの4行目、if (entry.isIntersecting) で設定しています。

終了条件の確認

交差地点を抜けるタイミングについて確認します。

発動とは異なり、要素の下端が抜けたら終了になります。(クラスが解除される)

Intersection Observerの解除条件

交差地点をこえると、if (entry.isIntersecting) がfalseになり、クラスがremoveされると。

サンプルの動作について

サンプルの場合、このrootMarginが狭く中心のみになっているため、ターゲットが1つしか発動しないわけです。

このrootMarginの値を調整すると、発動のタイミングがずれて、複数の画像が拡大されるようにもできます。

rootMarginの交差地点の条件色々

rootMarginの値が変わるとどうのように変化するかを図にしてみました。

rootMargin:0pxの場合

一番スタンダードな使い方の0pxの場合は、ビューポート全体が交差地点になります。

rootMargin 0%

表示エリアに入った時点で発動し、エリア外に行くと解除されます。

rootMargin:-20% 0pxの場合

上下に20%分のマージンが生まれます。
ちょっと(20%)スクロールした時点で発動すると。

rootMargin -20%

0pxだと、スクロールによる変化が感じられないので、変化を視認できるようにしたい場合は、ある程度マージンを持たせると良いですね。

上下で異なる値を指定した場合 rootMargin:-20% 0px 0px 0px

上右下左で指定できるので、上だけ-20%、下は0pxという指定もできます。

rootMargin -20% 0px

この場合、発動は少しスクロールしてから、解除はエリアを抜けたら、という動作になります。
入りは動くけど、出るときはそのままクラスを持たせたいときなどは、このような指定になりますね。
※ビューポートの外にいくとクラスは解除されます。

発動条件のif文について

今回、発動条件にしているのは if (entry.isIntersecting) にしています。
前回の記事ではif (entry.intersectionRatio <= 0) を条件にしていました。

//④交差時のアクション
function photo_set(entries){	
	entries.forEach(entry => {				
		if (entry.isIntersecting) {
			entry.target.classList.add("sample_on");
		}else{
			entry.target.classList.remove("sample_on");
		}					
	});
}

entry.はforEachのコールバック関数の引数です。
entryの中には、IntersectionObserverの色々な情報が含まれています。

entryの上にいる、entries.forEachのentriesには、ターゲットになる8つのliタグが配列で入っています。

entriesがどこから来たかというと、photo_set関数の引数です。

photo_set関数は、function createObserver()内で呼び出されており、function createObserver()のコールバック関数です。
コールバック関数として呼び出されたphoto_set()の引数には、IntersectionObserverEntryが渡されます。

ちなみにphoto_set()は私が勝手に命名しているだけで、どんな名前を付けても問題ありません。
callback()と命名して使うのが一般的なような気がします。

//③呼び出される関数
function createObserver() {
	let options = {
		root: null,
		rootMargin: "-50% 0px",				
		threshold: 0
	};
	let main_observer;
	main_observer = new IntersectionObserver(photo_set, options);
	target_item.forEach( (elem) => {
		main_observer.observe(elem);
	});   
}

entry.isIntersectingとは

ターゲットが交差地点に入ったら「true」を返し、交差地点外にいるときは「false」を返すブール値です。

交差地点にターゲットが触れたらtrueになり、クラス付与がされ、交差地点を超えたらfalseになり、クラスが外れます。

entry.intersectionRatioとは

こちらはターゲットが交差地点にどれだけ入っているかを0~1の数値で返します。
0 or 1 ではなく、0~1の小数点以下で返ってくるので細かく調整が可能です。

コードの流れを図解で整理

言葉だけだとよくわからないので流れを図解にしました。

Intersection Observerのコードの流れ

図解にしてもわかりやすいとはいいがたいのですが、頭で理解するより、使ってみて慣れる方が簡単です。

散々説明したあとにこういう言い方もあれなんですが、とりあえず作って動かしてから、理屈を理解する方が習得が早いと思います。

Intersection Observer API まとめ

今回のサンプルを私の仕事であるWEBページ制作で実際に使ったんですが、作れたもののイマイチ理解しきれていないを痛感し、記事にしました。

1枚ずつ拡大する際に、どこを調整するのかよくわかってなくて、試行錯誤(適当とも呼ぶ)した結果、思い通りに動きを再現できたのですが、なぜこうなるのかがわかっていなかったと。

冒頭に(自分用)と記したとおり、自分のための記事であります。

rootMarginだけじゃなく、threshold: 0をいじっても調整できると思うのですが、今のところ事足りてるので、いいかなと思ってます。

小難しい内容を解説するのは非常に時間がかかるのですが、自分の頭の整理になるので、今後もなにかあったらまとめたいと思います。

Intersection Observer APIは使い方次第でいろいろと面白いことができそうなので、今後も積極的に使っていきたいと思っています!

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

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

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

2,376円(税込)

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

独習JavaScript 新版

1,639円(税込)

独習JavaScript 新版

JavaScript 第7版

5,060円(税込)

JavaScript 第7版

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

2,178円(税込)

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

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

1,188円(税込)

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

JavaScript コードレシピ集

3,114円(税込)

JavaScript コードレシピ集

JavaScript[完全]入門

2,653円(税込)

JavaScript[完全]入門

交差監視の関連ページ

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

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

ノートPCスタンド
1位

ノートPCスタンド

ノートパソコンを横にしまうと結構な専有面積があるのですが、立てて収納できればわずか数cmで使えるので本当に快適です!

CPC改善策
2位

CPC改善策

Google Adsenseの収益最大化施策として、CPCの改善に取り組みました。 CPCの大幅改善に成功!やったぜ!

マッサージガン MYTREX
3位

マッサージガン MYTREX

慢性的な肩こりや首コリに悩まされているのでマッサージガンを購入してみました。 MYTREXのマッサージガンはいい!

独学
4位

独学

独学に限界を感じたことはないです。 人に頼りたいと思ったことはあってもすがりたいと思ったことはありません。

昭和記念公園
5位

昭和記念公園

東京都立川市にある国営昭和記念公園に家族で遊びに行きました。 広大な園内にはいろいろな遊具や春の花や大きな原っぱがあります。

Opera-03
6位

Opera-03

Opera-03のレビューです。 フラッグシップモデルのOpera-05との比較を交えてOpera-03の魅力をお伝えします。

撮影スペースDIY
7位

撮影スペースDIY

空いたスペースを活用して商品撮影スペースを自作しました。 白い布とLEDライトと空間があればだれでも作れる撮影BOX

USBマグネットホルダー
8位

USBマグネットホルダー

USBケーブルが机の周りでぴろぴろとしているとそれだけでなんだか散らかっているような気になりませんか?

胸の形
9位

胸の形

女性の絵を書いていたら、胸の形とその先にある風景を書かねばならんわけですが、正直良くわからないんですよね。

静岡家族旅行 計画編
10位

静岡家族旅行 計画編

2018年8月20日に毎年恒例の夏の家族旅行の行き先を静岡県に決定! 静岡県の選定理由と観光名所の選定の計画について。

カテゴリ一覧

オススメ商品レビュー

オススメ商品レビュー

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

WEB制作

WEB制作

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

カメラ

カメラ

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

美味しいもの

美味しいもの

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

Amazonプライム動画

Amazonプライム動画

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

旅LOG

旅LOG

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

プロフィール

プロフィール

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

日記

日記

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

thanks

thanks

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

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

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

2,376
(税込)