【jQuery】ページ内スムーススクロールの作り方を解説

【jQuery】ページ内スムーススクロールの作り方を解説

この記事の監修者

粟飯原匠 |プロデューサー

マーケティングを得意とするホームページ制作会社PENGINの代表。教育系スタートアップで新規事業開発を経験し、独立後は上場企業やレガシー産業のホームページ制作・SEO対策・CVR改善の支援を行うPENGINを創業。「ワクワクする。ワクワクさせる。」を理念に掲げてコツコツと頑張っています。

今回は多くのWebサイト・アプリに導入されている「スムーススクロール」の実装方法をまとめました。

記述パターンもそんなに多くないので、コードをストックしておけば様々なWebサイトで使いまわしできます。

ほぼjQueryの解説記事にはなりますが、今回もさくっとコピペで実装できるようコード付きで紹介していきます。

あわせて読みたい

CSSだけでスムーススクロールを実装する方法もあります!

>> 【CSSだけ】scroll-behaviorで超簡単にスムーススクロール実装!

スムーススクロールとは

ページ内リンク(アンカーリンク)をクリックすると、該当箇所にスッーと時間をかけて移動する演出のことです。

Image from Gyazo

スムーススクロール実装

Image from Gyazo

スムーススクロール未実装

何も仕掛けがないと右(スマホだと下)のGif画像のように一瞬でパッと遷移するため「移動した」という実感がありません。こうなると、ページ内に用意したコンテンツも見られないことになるため、サイトの離脱・直帰率が上がってしまう可能性があります。

多少時間をかけてスクロール移動することで、ユーザーが「移動してる」と実感できると共に、ページ内に「他にもコンテンツがあるのか」と感じてもらえることで、直帰率の低減に繋げられます。

※ちなみに「スムーズスクロール」と読むこともありますが意味は同じです。(smoothをどう日本語読みするか、という違いです)

今回はこちらのデモサイトを元に作成していきます。

HTML/CSS

ここに関しては特に説明しませんが、固定ヘッダーと高さ120vhのセクションを5つ用意しています。右下にはトップへ戻るボタンを設置しています。

HTML

<header>
  <nav>
    <ul class="header-inner">
      <li><a href="#section1">section1</a></li>
      <li><a href="#section2">section2</a></li>
      <li><a href="#section3">section3</a></li>
      <li><a href="#section4">section4</a></li>
      <li><a href="#section5">section5</a></li>
    </ul>
  </nav>
</header>
<main>
  <h2 id="section1" class="section">section1</h2>
  <h2 id="section2" class="section">section2</h2>
  <h2 id="section3" class="section">section3</h2>
  <h2 id="section4" class="section">section4</h2>
  <h2 id="section5" class="section">section5</h2>
  <p class="back-btn"><a href="#">Topに戻る</a></p>
</main>

CSS

* {
	box-sizing: border-box;
	list-style: none;
	margin: 0;
	padding: 0;
	text-decoration: none;
}

.header-inner {
	align-items: center;
	background-color: #1f5491;
	display: flex;
	height: 80px;
	justify-content: space-around;
	position: fixed;
	top: 0;
	width: 100%;
}

.header-inner li {
	line-height: 80px;
	text-align: center;
	transition: .5s;
	width: 100%;
}

.header-inner li:hover {
	background-color: #3e76b7;
	color: #111934;
}

.header-inner li:not(:nth-of-type(5)) {
	border-right: 1px solid #fff;
}

.header-inner li a {
	color: #e8e8e8;
	display: block;
}

@media screen and (max-width: 480px) {
	.header-inner li a {
		font-size: 12px;
	}
}

.section {
	background-color: #b5b5b5;
	display: flex;
	font-size: 40px;
	height: 120vh;
	justify-content: center;
	padding: 100px 0;
	width: 100%;
}

.section:nth-of-type(even) {
	background-color: #302f2f;
	color: #e8e8e8;
}

.back-btn {
	background-color: #1f5491;
	border-radius: 16px;
	bottom: 20px;
	height: 50px;
	line-height: 50px;
	position: fixed;
	right: 20px;
	text-align: center;
	transform: translateX(-50%);
	width: 120px;
}

.back-btn a {
	border-radius: 16px;
	color: #e8e8e8;
	cursor: pointer;
	display: block;
	height: 100%;
	transition: .3s;
	width: 100%;
}

.back-btn a:hover {
	background-color: #3e76b7;
	color: #111934;
}

jQueryコード全体

ここでは載せませんが、jQueryを使うのでCDNコードはHTMLのbodyの閉じタグ前に読み込んでおきましょう!詳しくはこちらから↓

>> 【最新版】jQueryのCDNを読み込む方法【超簡単です!】

$(function () {
  $('a[href^="#"]').click(function () {
    var href = $(this).attr("href");
    var target = $(href == "#" || href == "" ? 'html' : href);
    var position = target.offset().top;
   var speed = 500;
    $("html, body").animate({
      scrollTop: position
    }, speed, "swing");
    return false;
  });
});

順に解説していきます。

クリックしたアンカーリンクを取得する

$('a[href^="#"]').click(function(){

「aタグをクリックした時は~する」というイベントの書き出しからです。

属性(aタグだったらhrefやtarget)を取得するために[ ]で囲んでいます。

この [href^=”#”] ってのを見てウッとなった初学者の方は僕だけじゃないと思いたいんですが、これは「href が#から始まる要素を取得する」という記述になります。

「〇〇が××から始まる」という指定をするときに 〇〇^=×× で記述するわけですね。

※一部の解説記事では#をダブルクォーテンションで囲まない記述を紹介しているものもありますが、これだとjQueryのバージョンによっては動かないです。最新(2020年7月時点)の3.5.1ではダブルクォーテンションで囲まないと動きませんでしたのでご注意ください。

ちなみにこれはCSSの指定でも使えます。

属性セレクター – CSS: カスケーディングスタイルシート | MDN

取得したリンク先を変数に代入する

ここから4つの変数を設定します。

$(this).attr(“href”) とは

var href= $(this).attr("href")

クリックしたaタグのリンク先(href)の中身を取得(attr)して、定義した「href」という変数に代入する。

href=”#section1”であれば、変数にsection1が代入されます。

$(href == “#” || href == “” ? ‘html’ : href) とは

var target = $(href == "#" || href == "" ? 'html' : href);

またウッとくるやつですね。

href == “#” || href == “” と ? ‘html’ : href で分解してみます。

href == “#” || href == “”

href == “#” || href == “”

href == “#” or href == “”

hrefに入っているのが「#」または「空白」

ということを言っています。このへんはjsの基礎知識なので知っておかないといけないですね。

式と演算子 – JavaScript | MDN

? ‘html’ : href

「?」は三項演算子といって、if文を短縮する時などに用いられます。

式の答えとして:(セミコロン)で区切った値が、正の時は左(’html’)、誤の時は右(href)の値が入ります。

if (href == "#" || href == "") { var target = $('html'); } else { var target = $(href); }

分解して書くとこうなります。

変数targetに代入する内容は?

hrefに入っているのが「#」または「空白」の時は「’html’」を、どちらでも無ければ定義していた変数「href」の値(#section1など)

ということですね。ちなみにここで言う「’html’」はページのトップの事になります。

今回のHTMLだと、liタグ内のナビには#sectionと指定し、右下のトップへ戻るボタンは#のみ記述をしています。

条件 (三項) 演算子 – JavaScript | MDN

ページ上部からの距離を取得した値を変数に代入

var position = target.offset().top;

offset()は指定した要素のドキュメント左上からの距離を取得します。offset().topとすると上からの距離を取得します。

aタグをクリックして取得したid=#××が代入された変数「target」の、ドキュメント上部からの距離を変数「position」に代入する、という式になります。

スムーススクロールのスピードを設定

var speed = 500;

スクロールスピードの時間を変数「speed」に代入しています。これは後ろに記述しているanimate関数の時間指定で使用します。

ちなみに1,000=1秒なので、アンカーリンクから移動先まで0.5秒間かけて移動するという時間指定になります。数字が大きくなるとそれだけゆっくり移動する、ということです。

animate関数に直接速度指定を記述してもいいのですが、後々変更する場合変数でまとめておいたほうが管理しやすいです。

ここまでの変数の意味と流れを整理します。

  • href = クリックしたaタグに記述されているidの中身(#×× or # or 空白)
  • target = 変数hrefのif式の結果(#××かhtml)
  • position = 変数targetのドキュメント上部からの距離
  • speed = スクロールが完了するまでの時間

変数の値を元にアニメーションメソッドで動きを制御

$("html, body").animate({scrollTop:position}, speed, "swing");

$(“html, body”)と指定することで、ページのトップ位置を指定することになります。

ちなみにhtmlとbody両方指定するのは、ブラウザによって対応しているのがどちらか片方だからです。

また、animate関数の仕様はanimate(properties, [duration], [easing], [complete])です。[duration]以降の第二引数からは省略可能です。

properties(第一引数)

properties(プロパティ)にはCSSプロパティや、アニメーションで動きを加えたい内容を記載します。スムーススクロールにはscrollTopメソッドを記述します。

scrollTopは、「scrollTop()」とすると指定した位置(今回だったらブラウザ上部)からのスクロール量を取得し、()内に数値が入るとその位置まで移動する、というものです。

今回はここの数値を変数position(変数targetのドキュメント上部からの距離)で取得していますので、この位置まで移動することになります。

duration (第二引数)

durationはアニメーション開始から終了までの時間を指定します。

今回は変数speedがその数値になりますので0.5秒ということになります。

easing (第三引数)

easingはアニメーションの実行速度に緩急をつけるもので、「linear」だと一定速度で動き、「swing」だと始めがゆっくりで後半早くなります。デフォルトだとこの2種類から選択することになります。

今回はswingを選択しています。

スムーススクロールのjQuery実装まとめ

  1. クリックしたaタグのhrefの中身を取得
  2. 中身が#のみ、もしくは空白だったら高さ0、#idが取得できたらページトップからの位置(高さ)を取得
  3. 現在位置から取得した高さ(0〜)まで500ミリ秒かけて移動

こんな感じの動きをjQueryで指定しているということですね。これで完成です!

まとめ

ちょっとした修正を加えたい時は一つ一つの意味をザックリとでも理解しておくことが重要なので、コピペだけで済ましていた方は一度見直してみましょう。

また、同じメソッドを活用し、スクロールして画面領域に入った要素をふわっと表示させるアニメーション実装方法もまとめていますので是非チェックしてみてください!


また、当記事を読まれている方の中にはWeb制作初学者の方もいるかと思います。デザインやコーディングの基礎知識を学びたい方向けの記事を用意しているので是非見ていってください!

PENGIN無料コーディング課題

オススメ書籍紹介

オススメUdemy講座紹介