サイトロゴ

Enjoy Creating
Web & Mobile Apps

MENU BOX
WEB
MOBILE
OPEN

ホーム

 > 

 > 

【JavaScript】スクロールで現れるトップへ戻るボタン

【JavaScript】スクロールで現れるトップへ戻るボタン

この記事にはプロモーションが含まれています。

Webページでは情報量が多くなればなるほど、どうしても縦に長くなってスクロール量が多くなってしまいます。
そうなると困るのが、ページを読んでいる途中で一旦トップに戻りたくなった場合です。

そんな時の対処法としてよく使われるのが、トップへ戻るボタンの設置です。
ただし、トップへ戻るボタンはある程度画面をスクロールさせた状態でなければ必要ないものであり、常に表示させたままでは邪魔になってしまいますよね。

画面がある程度スクロールされた…という検知はHTML/CSSではできず、JavaScriptでしか処理できません。

今回は、『ある程度スクロールされたことを検知するプログラム』を使って、スクロール量によって表示⇔非表示が切り替わるトップに戻るボタンを実装してみようと思います。

– 目次 –

スクロール量を計測する

まずはJavaScriptを使って画面がどれくらいスクロールされたか?を検知してみましょう。

Webページは一般的に縦方向にスクロールされるので、縦方向のスクロール量を測るプログラムをご紹介します。

縦方向のスクロールを計測
let scrollY = window.scrollY

しかし、これだけではページを開いた瞬間にスクロール量を計測してしまうということになってしまいます。

ページが開かれた瞬間はスクロールされていない状態なので、scrollY = 0という結果になります。

   let scrollY = window.scrollY;  
   console.log(scrollY);  //0
サンプルコードの検証ツール表示結果
表示結果

そこで、addEventListenerの‘scroll’を使って、スクロールされるたびにスクロール量が計測されるようにしてみましょう。

   window.addEventListener('scroll', () => {   
	let scrollY = window.scrollY;
	console.log(scrollY);
   });
サンプルコードの検証ツール表示結果2
スクロールのたびに計測される

これでユーザーが画面をスクロールするたびに、現在の縦方向のスクロール量を検知することができるようになりました。

今回は処理をわかりやすくするためイベントリスナーのscrollイベントのみ使っていますが、他にもsetInterval()メソッドを使って、一定時間おきに処理をするという方法もあります。

次は、スクロール値が一定の数値以上になった場合に処理をするという、条件分岐(if構文)を使ってプログラミングを仕上げていきしょう。

    POINT!
  1. ・縦方向のスクロール量は、window.scrollYで計測できる!
  2. ・しかしそのままではページが開かれた瞬間にスクロール量が計測されてしまう!
  3. ・イベントリスナーのscrollやsetInterval()メソッドを使って、定期的に検知できるようにしておこう!

スクロール量に応じた条件分岐

適時スクロール量を計測できるようにしたら、次はスクロール量がX以上のときにAという処理、X未満の時はBという処理…という条件分岐という設定を行っていきます。

条件分岐は、if文を使います。

if構文
if (条件) { 処理A }
else { 処理B }

ifは( )かっこ内の条件に当てはまる時、elseはifで指定した条件に当てはまらない時の処理を担当します。

また、else if()を使って複数の条件分岐を設定することも可能ですが、今回は任意のスクロール値以上の時とそれ以外の時という条件で処理できます。
なので、ifとelseを1つずつ使ってプログラムを組めばOKです。

上記を踏まえて、サンプルコードを確認していきましょう。

まず、header要素とsection要素にそれぞれ高さを指定して画面スクロールができるようにしておきます。
そしてif文でスクロール値が150以上になったら、コンソール画面に”over”と表示させるようにプログラムしています。
(150未満の時は”not over”と表示)

HTML

   <header id="top">header</header>
   <section>セクション1</section>
   <section>セクション2</section>
   <section>セクション3</section>

CSS

   header {
	height: 100px;
	background-color: lightblue;
	display: grid;
	justify-content: center;
	align-content: center;
   }
   section {
	height: 500px;
	display: grid;
	justify-content: center;
	align-content: center;
	/*分かりやすく背景色*/
	background-color: azure;
   }
   section:nth-child(2n) {
	background-color: lightgoldenrodyellow;
   }

JavaScript

   window.addEventListener('scroll', () => {
	let scrollY = window.scrollY;
	if(scrollY >= 150) {
		console.log('over');
	}
	else {
		console.log('not over');
	}
   });

下の動画は、サンプルコードをコンソール画面で確認した様子を録画したものです。
▼クリックすると再生されます(ファイルサイズ:154KB)

表示結果

縦のスクロール値によって、”over”と”not-over”が切り替わっているのが確認できますね。

次の章では、スクロール値によって要素のclassをつけ外しするという処理を行なっていきます。

    POINT!
  1. ・特定の条件下で処理を実行するには、if文を使う!
  2. ・if( )のかっこの中に条件を指定する ※else if()で複数の条件を使用することも可!
  3. ・elseはifで指定した条件に当てはまらない場合に処理が実行される!

スクロール量によってclassを操作

スクロールの検知とスクロール値の測定、そしてその値による条件分岐の準備が整ったら、条件分岐で要素のclassを操作していきます。

調整のポイントですが、まず普段はトップへ戻るためのボタンを隠すCSS調整をしておきます。
そして、スクロール値が一定以上になった場合に要素を表示させるためのclassを付与し、スクロール値が一定未満になった場合には付与したclassを外すことで実装可能です。

スクロール値が一定値未満
{ opacity: 0; visibility: hidden; }
スクロール値が一定以上
{ opacity: 1; visibility: visible; }

classの付与と削除には、classList.add()及び、classList.remove()を使います。

sampleというclassを付与
classList.add(‘sample’)
sampleというclassを削除
classList.remove(‘sample’)

上記のJavaScriptを利用して、‘active’というclassを付け外しすることにより、トップへ戻るボタンの表示⇔非表示をスクロール値によって切り替えていきます。

なお、トップへ戻るための処理はa要素を使ったページ内リンクで簡単にできます。
※ページ内リンクに関する記事はこちら

ボタンにクリックイベントを設定してJavaScriptでページ上端までスクロールさせる方法もありますが、プログラムを簡素化したい場合はページ内リンクが便利です。

以上を踏まえて、サンプルコードと表示結果を確認していきましょう。

HTML

   <header id="top">header</header>
   <section>セクション1</section>
   <section>セクション2</section>
   <section>セクション3</section>

   <!--トップへ戻るボタン-->
   <a class="return_top" href="#top">></a>  

CSS

   html {
	scroll-behavior: smooth;
   }
   header {
	height: 100px;
	background-color: lightblue;
	display: grid;
	justify-content: center;
	align-content: center;
   }
   section {
	height: 500px;
	display: grid;
	justify-content: center;
	align-content: center;
	/*分かりやすく背景色*/
	background-color: azure;
   }
   section:nth-child(2n) {
	background-color: lightgoldenrodyellow;   
   }
   .return_top {
	background-color: white;
	color: black;
	text-decoration: none;
	position: fixed;
	right: 20px;
	bottom: 30px;
	width: 40px;
	height: 40px;
	border: solid thin;
	border-radius: 50%;
	display: grid;
	justify-content: center;
	align-content: center;
	transform: rotate(-90deg);
	transition: .4s;
	/*普段は隠しておく*/
	opacity: 0;
	visibility: hidden;
   }
   .return_top.active {
	/*activeが付いたら表示*/
	opacity: 1;
	visibility: visible;
   }

JavaScript

   const returnTop = document.querySelector('.return_top');  
	
   window.addEventListener('scroll', () => {
	let scrollY = window.scrollY;
	if(scrollY >= 150) {
		//classにactive付与
		returnTop.classList.add('active');
	}
	else {
		//classからactive削除
		returnTop.classList.remove('active');
	}
   });

表示結果

上のサンプルでは、少しスクロールさせるとトップへ戻るボタン(a要素)が現れ、一番上までスクロールを戻すとボタンが消えることが確認できます。
※上のサンプルで動作が確認できなかった場合は、下のサンプルでお試し下さい。

header
セクション1
セクション2
セクション3

なお、トップへ戻るボタンは右下の位置に固定させることが多いです。

横書きの日本語は左から右に読むので必然的に文頭は左側になり、リストの番号なども全て左側に来ることになります。
となれば、左側にボタンが表示されていると邪魔になりますよね。

右側の方が空白(余白)を作りやすく邪魔になりにくいので、右下あたりに配置するのが良いというわけです。

ただし、右下でもボタンの大きさや形によっては邪魔になるので気をつけましょう。

    POINT!
  1. ・普段はトップへ戻るボタンをCSSで隠しておき、特定のclassが付与されたら出現するようにしておこう!
  2. ・スクロール値が一定以上になった時、classList.add()で要素にclassを付与しよう!
  3. ・スクロール値が一定未満に戻った場合は、classList.remove()で付与したclassを削除しよう!
– 関連記事 –

今回の動画で紹介したコード!

今回の解説動画で使用したコードです。学習用としてご自由にコピペしてお使い下さい。(※スクロールできます)

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width,initial-scale=1">    
<title>scrolly</title>
	<style>
	html {
		scroll-behavior: smooth;
	}
	header {
		height: 100px;
		background-color: lightblue;
		display: grid;
		justify-content: center;
		align-content: center;
	}
	section {
		height: 500px;
		display: grid;
		justify-content: center;
		align-content: center;
		/*分かりやすく背景色*/
		background-color: azure;
	}
	section:nth-child(2n) {
		background-color: lightgoldenrodyellow;
	}
	.return_top {
		background-color: white;
		color: black;
		text-decoration: none;
		position: fixed;
		right: 30px;
		bottom: 30px;
		width: 40px;
		height: 40px;
		border: solid thin;
		border-radius: 50%;
		display: grid;
		justify-content: center;
		align-content: center;
		transform: rotate(-90deg);
		transition: .4s;
		opacity: 0;
		visibility: hidden;
	}
	.return_top.active {
		opacity: 1;
		visibility: visible;
	}
	</style>
</head>

<body>
	<header id="top">header</header>
	<section>セクション1</section>
	<section>セクション2</section>
	<section>セクション3</section>
<!--トップへ戻るボタン-->
	<a class="return_top" href="#top">></a>
	
<script>
	const returnTop = document.querySelector('.return_top'); 
	window.addEventListener('scroll', () => {
		let scroll_Y = window.scrollY;
		if(scroll_Y > 150) {
		   returnTop.classList.add('active');
		   }
		else {
			returnTop.classList.remove('active');
		}
	});
</script>
</body>
</html>

« »

カテゴリーリンク

著者について- author profile -

ROYDOプロフィール写真
Michihiro

モバイルアプリ(iOS・Android)ディベロッパー&デザイナー

これまでに、可読性の高いカラーパターンを自動で生成するアプリや、『第3火曜日』といった形式で通知をスケジュールできるアプリなどを制作。

サブでWebデザイン・フロントエンドエンジニアとしても活動しています。

📝ツール・言語:JavaScript/React Native/Kotlin/Android Studio/Swift/SwiftUI

🎓資格:応用情報技術者/基本情報技術者/ウェブデザイン技能検定3級

Twitterアイコン Instagramアイコン