jQueryでスクロールするとふわっと表示

jQueryでスクロールするとふわっと表示
Image by Sarah Richter from Pixabay

2020.12.08(更新日:2021.03.22)

jQueryを使いスクロールし、ある時点で「ふわっと」表示するやつ。
CSSセレクタの切り替えで実装…なのだが、よく忘れるのでまとめておく。

この記事は1年以上経過しています。内容的に古い場合があります。

HTML

セレクタ名は何でもいいけど、今回は効果を付けたい要素を「fadeblock」とする。

/* HTML */
<div>
  <div class="fadeblock">ふわっと表示</div>
  <div class="fadeblock">ふわっと表示</div>
  <div class="fadeblock">ふわっと表示</div>
</div>

jQuery読み込み

何はなくともこれを先読み。

/* CDN経由なら */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
/* ダウンロードファイルを読み込むなら */
<script src="< FILE_PATH >/jquery-3.5.1.min.js"></script>

ダウンロードの場合ファイル構成に合わせて< FILE_PATH >は適宜変更。

CSS

CSSで該当部分のclassセレクタを指定。今回は下にある程度スクロールされたら「ふわっと表示」、上にある程度スクロールされたら(表示範囲外になりそうなところで)「ふわっと消える」を実装したいので、フェードイン・アウトのアニメーションをそれぞれ指定する。

/* フェードインのセレクタ */
.fadeInUp {
  -webkit-animation-fill-mode:both;
  animation-fill-mode:both;
  -webkit-animation-duration:1s;
  animation-duration:1s;
  -webkit-animation-name: appearfade;
  animation-name: appearfade;
}
@-webkit-keyframes appearfade {
  0% {
    opacity: 0;
    -webkit-transform: translateY(30px);
    transform: translateY(30px);
  }
  100% {
    opacity: 1;
    -webkit-transform: translateY(0);
    transform: translateY(0);
  }
}
@keyframes appearfade {
  0% {
    opacity: 0;
    -webkit-transform: translateY(30px);
    transform: translateY(30px);
  }
  100% {
    opacity: 1;
    -webkit-transform: translateY(0);
    transform: translateY(0);
  }
}

/* フェードアウトのセレクタ */
.fadeOutDown {
  -webkit-animation-fill-mode:both;
  animation-fill-mode:both;
  -webkit-animation-duration:1s;
  animation-duration:1s;
  -webkit-animation-name: leavefade;
  animation-name: leavefade;
}
@-webkit-keyframes leavefade {
  0% {
    opacity: 1;
    -webkit-transform: translateY(0);
    transform: translateY(0);
  }
  100% {
    opacity: 0;
    -webkit-transform: translateY(30px);
    transform: translateY(30px);
  }
}
@keyframes leavefade {
  0% {
    opacity: 1;
    -webkit-transform: translateY(0);
    -ms-transform: translateY(0);
    transform: translateY(0);
  }
  100% {
    opacity: 0;
    -webkit-transform: translateY(30px);
    -ms-transform: translateY(30px);
    transform: translateY(30px);
 }
}

ベンダープリフィクスがあると倍以上長くなるのでややっこしい…。
「animation-duration」や「translateY」の値はお好みで変更。

jQuery

/* jQuery */
(function($) {
	$.fn.fadeblock = function() {
		var scroll = $(window).scrollTop();
		var windowHeight = window.innerHeight ? window.innerHeight: $(window).height();
		$(this).each(function(){
			var elm = $(this);
			var imgPos = $(this).offset().top ? $(this).offset().top : $(this).get(0).offsetTop;
      //すでに表示されている時
			if( windowHeight > imgPos ){
				elm.removeClass('fadeOutDown').addClass('fadeInUp');
      //スクロール時の処理
			} else {
				if ( scroll > imgPos - windowHeight + windowHeight/6 ){
					elm.removeClass('fadeOutDown').addClass('fadeInUp');
				} else {
					elm.removeClass('fadeInUp').addClass('fadeOutDown');
				}
			}
		});
	}

	$(window).on('scroll',function(){
		$( '.fadeblock' ).fadeblock();
	});
})(jQuery);

setTimeoutは面倒なのでしなかったけど、スームズに動いた。
必要ならば12行目の「windowHeight/6」の数字を変更。
あまり数字を大きくするとフェードアウト効果が薄れるが、その辺はお好みで。

バリバリのエンジニアではないので、野暮ったいコードかもしれないが良ければご参考に。

最近ネイティブなJSが流行りなので

この場合は当然jQueryは必要ない。scriptタグで囲むのは忘れずに。

/* javascript */
var isRunning = false;
let array = document.getElementsByClassName( "fadeblock" );

window.addEventListener('scroll', function() {
	if (!isRunning) {
		isRunning = true;
		window.requestAnimationFrame(function() {
			fadeFunc();
			isRunning = false;
		});
	}
},{passive: true});

var fadeFunc = function () {
	let scroll = document.documentElement.scrollTop || document.body.scrollTop;
	let wHeight = window.innerHeight;
	array = Array.from( array );
	array.forEach( function ( element ) {
		let topPos = element.offsetTop;
		//すでに表示されている時
		if( wHeight > topPos ){
			element.classList.remove('fadeOutDown');
			element.classList.add('fadeInUp');
		//スクロール時の処理
		} else {
			if ( scroll > topPos - wHeight + wHeight/6 ){
				element.classList.remove('fadeOutDown');
				element.classList.add('fadeInUp');
			} else {
				element.classList.remove('fadeInUp');
				element.classList.add('fadeOutDown');
			}
		}
	});
}

ECMAScriptって言うらしいが「脱jQuery」を狙って最近触り始めたので定義がわかってなく、慣れないコードで少々苦戦。単なるjQuery版の焼き直しだけどご参考に。