バニラJavaSqriptでスクロールアニメーション

webあれこれ

バニラJavaSqriptを使ってスクロールアニメーションを作ってみよう!

jqueryでは簡単に実装できるスクロールアニメーションですが、バニラJSでどう実装するのかやってみました。

See the Pen スクロールアニメーション javascript by shimashima (@chaytee) on CodePen.

Intersection Observerの基本

まずは、簡単な要素の作成をし、その要素がブラウザ画面に入ったり出たりする時を確認。
ここではclassをつけたり外したり。※codepenでは少し見にくいかもしれません。

See the Pen Untitled by shimashima (@chaytee) on CodePen.

コード記述の流れ

①DOMの取得
②動かしたい内容
③オプションがあれば
④インスタンスされたオブジェクトの生成。引数にコールバック関数を取る。第二引数はあればオプションを渡す。
⑤observeメソッドの発動。

const child = document.querySelector('.child');

//動きの詳細を決める
const cb = function(entries, observer){
	entries.forEach(entry => {
		//渡ってきた要素が画面内に入ってきた場合
		if(entry.isIntersecting) {
			//console.log('入った');
			entry.target.classList.add('inview');
			//監視解除について記述もできる
			//observer.unobserve(entry.target);
		} else {
			//画面外へ出た場合
			//console.log('出た');
			entry.target.classList.remove('inview');
		}

	});
}
//オプション
const option = {
	//詳細な交差設定
	root: null,
	//要素の交差のオプションをmarginでつける(0もpxがいる)
	rootMargin: "-50% 0px -300px 0px",
	//進行方向の交差のオプション(進行方向と要素の先頭が0,後ろが1)
	threhold: 0
}
//ioはインスタンスされたオブジェクト。コールバック関数を渡されている。
const io = new IntersectionObserver(cb, option);
//監視したい対象のDOM
io.observe(child);

スライドアニメーションの詳細の説明

//addEventListener() メソッド
//optionsは省略可能

target.addEventListener(type, listener [, options]);

DOMContentLoaded・・・HTML の初期文書が完全に読み込まれ解釈された時点で発生し、スタイルシート、画像、サブフレームの読み込みが完了するのを待ちません。

document.addEventListener('DOMContentLoaded', function () {

	const cb = function (el, isIntersecting) {
		if (isIntersecting) {
			el.classList.add('inview');
		}
		//要素が画面を外れたらクラスを外す
		else {
			el.classList.remove('inview');
		}
	}

	const so = new ScrollObserver('.cover-slide', cb);
});
//クラス化したもの
class ScrollObserver {
	constructor(els, cb, options) {
		this.els = document.querySelectorAll(els);
		//デフォルトオプションの設定
		const defaultOptions = {
			root: null, //交差点の設定
			rootMargin: "0px", //交差点の位置を設定
			threshold: 0, //交差点の進行方向の上部を選択
			once: true
		};
		this.cb = cb;
		//デフォルトオプションとoptionsのmarge
		this.options = Object.assign(defaultOptions, options);
		//this.once = this.options.once;
		this._init();
	}
	_init() {
		const callback = function (entries, observer) {

			//entriesの配列--entry/entries
			entries.forEach(entry => {
				//entryに要素があれば処理を行う
				if (entry.isIntersecting) {
					this.cb(entry.target, true);
					//一度だけ読み込む場合
					//if(this.once) {
					//observer.unobserve(entry.target);
					//}
				} else {
					this.cb(entry.target, false);
				}
			});
		};
		//監視している対象が交差した時に起動する
		this.io = new IntersectionObserver(callback.bind(this), this.options);

		//複数から一つづつ取り出して監視対象
		this.els.forEach(el => this.io.observe(el));
	}
	//不用になったら解除する
	//destory() {
		//this.io.disconnect();
	//}
}

タイトルとURLをコピーしました