web関連

【javascript】Intersection ObserverAPIについて

スクロールイベント以外で遅延読み込みやスクロールアニメーションを実装することができるIntersection ObserverAPIを使った時の備忘録
Intersection ObserverAPIについての詳細の解説はしません。

scrollイベントとの違い

ざっくり書き出し

  • scrollイベントは常に発火し続けるが、Intersection ObserverAPIは画面に入る時のみ発火なのでパフォーマンスがいい
  • scrollイベントが使えない慣性スクロールサイトでも使える
  • ie11に対応させるためにはpolyfillを読み込ませる必要がある

実際使用したのは慣性スクロールを使ったサイトで、「スクロール量取れねぇ!やべぇ!!」という状況に陥ったため使用
使用感としてはモダンブラウザは問題ないし、スマホも問題なかった

画面内に入ってから発火するというコストパフォーマンスが良い半面、スクロールアニメーションを実装したサイト下部で再読み込みし上にスクロールした時にアニメーションが発火するということもある(あまり問題視してないし、書き方で対応?できると思う)

それでは実際に使ってみようと思う

ソースコードとサンプル

画面内に入ったら一度だけ発火し、consoleに要素を出力をするサンプルコード

<style>
.div{
	height: 100vh;
	display: flex;
	align-items: center;
	justify-content: center;
}
</style>

<div class="div" style="background: red;">テスト1です</div>
<div class="div" style="background: blue;">テスト2です</div>
<div class="div" style="background: green;">テスト3です</div>
<div class="div" style="background: yellow;">テスト4です</div>
<div class="div" style="background: pink;">テスト5です</div>
<div class="div" style="background: white;">テスト6です</div>


<script src="./intersection-observer.js"></script>
<script>
var elements = [].slice.call(document.querySelectorAll(".div"));

// 要素が画面内に入ったときの処理用関数
var callback = function(entries){
	entries.forEach(function (entry) {
		if (entry.isIntersecting) {
			var element = entry.target;
			// ここに要素が画面内に入ったら実行したい処理を書く
			console.log(element);

			elementObserver.unobserve(element);// 監視終了(設定しないと何度も発火する)
		}
	});
}

// Intersection observer のオプション
var option = {
	rootMargin: "0px 0px -10% 0px",// 画面下部から10%の位置を要素が通過したら発火
}

// Intersection observer の作成
var elementObserver = new IntersectionObserver(callback, option);

// 処理の実行
elements.forEach(function (element) {
	elementObserver.observe(element);
});
</script>
デモ
IE11対応、要素が画面に入ったらconsoleに要素を出力

あえてcallbackoptionと分けたけど一緒に書いた方が楽

<script>
let elements = [].slice.call(document.querySelectorAll(".div"));

let elementObserver = new IntersectionObserver(function (entries, observer) {
	entries.forEach(function (entry) {
	  if (entry.isIntersecting) {
	    let element = entry.target;

	    console.log(element);

	    elementObserver.unobserve(element);
	  }
	});
}, {
	rootMargin: "0px 0px 10% 0px",
});

elements.forEach(function (element) {
	elementObserver.observe(element);
});
</script>

IE11はpollyfileを読み込む必要がある

<script src="./intersection-observer.js"></script>

pollyfileは以下から落とす

https://github.com/w3c/IntersectionObserver

2022年6月16日にie11もサポート終了するのでpolyfillもその時までだね

IE11の時だけ何かしたいのであれば以下の条件分岐を使用できる

if (!('IntersectionObserver' in window)) {
	// IE11の時の処理
}

本当は動的に「intersection-observer.js」ファイルを読み込ませたかったんだけど読み込み順の制御をしないと駄目で面倒だったので頓挫

Leave a Comment

入力エリアすべてが必須項目です。メールアドレスが公開されることはありません。

内容をご確認の上、送信してください。