お問い合わせはコチラから

ページスクロールを検出する軽くて簡単なjavascript

サイト運営

TOPに戻るボタンがあるサイトをよく見かけます。

そのTOPに戻るボタンは、ページを読み込んだ瞬間は表示されなくて、下にスクロールすると表示されたりします。

このギミックは、javascriptとCSSで実現している場合が殆どだと思います。

この記事では、ページスクロールを検出するとても簡単なスクリプトをご紹介します。

ページスクロールを検出するjavascript

ページTOPから100pxスクロールしたら、スクロールしたと判定

  • Intersection observerを使用、動作は軽い。
  • ページTOP付近にl-scrollObserverをCSSで配置し、監視
  • l-scrollObserverがviewportに入ったり、viewportから消えると発火し、toggleScrollClassを呼び出だす。
  • toggleScrollClassは、htmlタグのdata-scrolledをトグルさせる。
  • l-scrollObserverの位置をCSSで変えると、スクロール検出位置を変更できる。
function setScrollEvent() {
	// IntersectionObserverをブラウザがサポートしているかどうか
	const isObserveSupported =
		window.IntersectionObserver && 'isIntersecting' in IntersectionObserverEntry.prototype;
	if ( ! isObserveSupported ) return;

	const observerOptions = {
		root: null,
		rootMargin: '0px',
		threshold: 0,
	};
	const scrollObserver = new IntersectionObserver( ( entries ) => {
		entries.forEach( ( entry ) => {
			toggleScrollClass( ! entry.isIntersecting );
		} );
	}, observerOptions );

	const theObserver = document.querySelector( '.l-scrollObserver' );
	scrollObserver.observe( theObserver );
}

function toggleScrollClass( isScrolled ) {
	if ( isScrolled ) {
		document.documentElement.setAttribute( 'data-scrolled', 'true' );
	} else {
		document.documentElement.setAttribute( 'data-scrolled', 'false' );
	}
}
<?php
add_action('wp_footer',function(){
?>
<div class="l-scrollObserver" aria-hidden="true"></div>
<?php
});
.l-scrollObserver {
    display: block;
    height: 1px;
    left: 0;
    pointer-events: none;
    position: absolute;
    top: 100px;
    visibility: hidden;
    width: 100%;
    z-index: 1000;
}

参考:https://github.com/loos/arkhe/blob/4618f0f0eddce34883683355a8eff40529fbde36/src/js/modules/setScrollEvent.js

カスタマイズする場合のポイント

スクロール検出位置を変更する

CSSのtop: 100px;を好きな数値に変えれば、スクロール検出位置が変わります。

ページのTOPから100pxの位置が画面から消えると、発火するのがデフォルトです。

attributeをつける対象を変更する

attributeをつける対象が<html>タグなので、違う対象に変える場合はエレメントを変更します。

function toggleScrollClass( isScrolled ) {
var elm = document.querySelector('セレクタ');
	if ( isScrolled ) {
		elm.setAttribute( 'data-scrolled', 'true' );
	} else {
		elm.documentElement.setAttribute( 'data-scrolled', 'false' );
	}
}

チャタリングする不具合現象が起きた

このスクリプトは、ヘッダーサイズをscrollの有無に合わせてリサイズするギミックと組み合わせると、変化点付近でマウスを止めた時にチャタリングする現象が発生しました。

ArkheやSWELLなどでも使われているものですが、それらのテーマはヘッダー高さを変更していないので、問題が起きていないようです。

原因ははっきりわからないのですが、ある程度揺れてもスクロールの有無の判定がガチャつかないようにヒステリシス特性を持たせた方が安定すると思います。

幸い、Intersection Observerには要素が完全に表示、完全に非表示という区別で動きを分けらえるので、それを組み合わせると問題なくなりました。

<script>
//オプション
const options = {
  //対象の要素が領域に出入りする際(0)との全体が表示される際(1)を指定
  threshold: [0, 1],
}
 
const span = document.querySelectorAll('.l-scrollObserver');
 
//コールバック関数の定義
const callback = (entries) => {
  //各 entry に対して
  entries.forEach( (entry) => {
    //交差の割合が1以上の場合(全体が見えている場合)
    if (entry.intersectionRatio >= 1) {
      entry.target.classList.add('allInView');
      span.textContent = '.allInView';
	document.documentElement.setAttribute( 'data-scrolled2', 'false' );
    //交差の割合が0の(見えなくなった)場合
    } else if(entry.intersectionRatio === 0){
      entry.target.classList.remove('allInView');
      span.textContent = '';
	document.documentElement.setAttribute( 'data-scrolled2', 'true' );
      //console.log('removed'); //確認用
    }
  });
}
 
const observer = new IntersectionObserver(callback, options);
const targets = document.querySelectorAll('.l-scrollObserver');
targets.forEach( (elem) => {
  observer.observe(elem);
});
</script>
Intersection Observer API の使い方
Intersection Observer API の基本的な使い方やサンプルを掲載しています。要素が画面内に入ったらアニメーションを開始するサンプルやグラデーションをアニメーションで表示するサンプル、スクロールスパイのサンプル、及びオプシ...

まとめ

あくまでも、ページTOPからスクロールしたかしてないかだけの判定ですので、ファーストビューをスクロールの有無で切り替える用途では便利だと思います。

かなりラフなスクロール検出ですが、その分、コードも短く軽い実装だと思います。

ページTOP以外の要素を監視して同じことを行う場合は、逆方向スクロールのことを考えないといけないので、今回の実装では対応できません。

この記事を書いた人
ブーン

はるばる日本よりオランダ王国へやってまいりました。
自分の経験が少しでも参考になれば嬉しいです。
お問い合わせは、『こちら』からお願い致します。

\ブーンをフォロー/
スポンサーリンク
サイト運営
\シェアお願いします!/
\ブーンをフォロー/
こんな記事も読まれています

失敗しないレンタルサーバーランキング

mixhost

不正アクセスに強くて使いやすいおススメサーバー
\本サイトで利用中/
メリット①:自動ウィルス駆除対応
メリット②:サイトの表示速度が速い!
メリット③:転送量の上限が多い!
メリット④:自由にプラン変更ができ、アクセス増にも対応できる!
メリット⑤:バックアップデータが無料で復元できる!
メリット⑥:Wordpressが簡単にインストールできる!
メリット⑦:どのプランでも初期費用が無料!
メリット⑧:10日間の無料お試し期間と30日の返金保証!

Conoha Wing

国内Wordpress最速の最強サーバー
メリット①:圧倒的な表示速度
メリット②:レンタルサーバーと独自ドメインがセットでお得◎
メリット③:プラン変更はすべてのプランで自由自在
メリット④:一か月の利用転送量の制限が緩い(9TB~)
メリット⑤:WordPresサイトの移行が簡単

エックスサーバー

国内シェアNo1の安定性と実績が魅力。ALL SSDで死角なしの万能サーバー。
メリット①:サイトの表示速度が安定して速い!
メリット②:アクセス負荷に強くて安定性が高い!
メリット③:24時間365日の充実サポートで安心!電話サポートもあり!
メリット④:転送量が多い!
メリット⑤:自動バックアップ機能付き!
メリット⑥:WordPressが簡単にインストールできる!
メリット⑦:10日の無料お試し期間がある!

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