JavaScriptについての記事

IntersectionObserverを使って複数要素にスクロールイベントを設定!!

IntersectionObserver を使って複数要素に スクロールイベントを設定!!

IntersectionObserverを使用すると、スクロールイベントを簡単に作成することができます。
今回は、複数の要素に対してスクロールイベントを設定する方法を紹介します。

複数要素に画面内に入った際に発火するスクロールイベントを設定

const animation = (animContent,optionRoot,optionMargin,optionThreshold) => {
	const $animClass = document.getElementsByClassName(animContent);
	const $animClassArray = Array.prototype.slice.call($animClass);

	for (let $animItem of $animClassArray) {
		let elemPos = $animItem.getBoundingClientRect().top + window.scrollY
		let scroll = document.documentElement.scrollTop;
		if (scroll > elemPos){
			$animItem.classList.add('scrollin');
		}
	}

	const options = {
		root: optionRoot,
		rootMargin: optionMargin,
		threshold: optionThreshold
	}

	const cb = (entries) => {
		entries.forEach( (e) => {
			if (entry.isIntersecting) {
				e.target.classList.add('scrollin');
			}
		});
	}

	const observer = new IntersectionObserver(cb, options);

	$animClassArray.forEach( (animClass) => {
		observer.observe(animClass);
	});

}

const animContents = ['クラス名','クラス名','クラス名'];

animContents.forEach( (animElm) => {
	animation(animElm,null,'-100px 0px',0);
});

以上が、IntersectionObserverを複数の要素に適用するためのコードです。

スクロールイベントを発生させたい要素を配列に代入します。

const animContents = ['クラス名','クラス名','クラス名'];

配列を使用することで、同様の動きをつけたい複数の要素に対して、エフェクトを付与することができます。

IntersectionObserverの動きを作成するための関数を作成します。

animationという関数を作成し、その中にIntersectionObserverで交差した際の動きを作成します。

const animation = (animContent,optionRoot,optionMargin,optionThreshold) => {
	const $animClass = document.getElementsByClassName(animContent);
	const $animClassArray = Array.prototype.slice.call($animClass);

	for (let $animItem of $animClassArray) {
		let elemPos = $animItem.getBoundingClientRect().top + window.scrollY
		let scroll = document.documentElement.scrollTop;
		if (scroll > elemPos){
			$animItem.classList.add('scrollin');
		}
	}

	const options = {
		root: optionRoot,
		rootMargin: optionMargin,
		threshold: optionThreshold
	}

	const cb = (entries) => {
		entries.forEach( (e) => {
			if (entry.isIntersecting) {
				e.target.classList.add('scrollin');
			}
		});
	}

	const observer = new IntersectionObserver(cb, options);

	$animClassArray.forEach( (animClass) => {
		observer.observe(animClass);
	});

}

今回は各配列要素が画面内に入った際にscrollinクラスを付与する動きを作成しました。

関数を実行する際にオプションを設定します

animContents.forEach( (animElm) => {
	animation(animElm,null,'-100px 0px',0);
});

animation関数の引数にオプションを指定することで、異なる配列に対して異なるオプションを設定することができます。

指定した要素がスクロール量を超えている場合

for (let $animItem of $animClassArray) {
	let elemPos = $animItem.getBoundingClientRect().top + window.scrollY
	let scroll = document.documentElement.scrollTop;
	if (scroll > elemPos){
		$animItem.classList.add('scrollin');
	}
}

animation関数の中に記述してある上記のコードは、ページリロード後やページを戻った際に、現在のスクロール量が対象要素を超えている場合にクラスが付与された状態にしたいので、現在のスクロール量と要素の位置を取得し比較してクラスを付与させるか判別させています。

おわりに

IntersectionObserverを使用することで、windowオブジェクトのscroll()メソッドよりも負荷が少なく、パフォーマンスの面でも優れています。ぜひ、IntersectionObserverを使ったスクロールイベントの実装に挑戦してみてください。