MENU
カテゴリー
だいち
このブログの管理者
異業種で仕事をしながら、副業でWeb制作をしているアラサーリーマンです。
日々の勉強の記録や、お役立ち情報を発信していきます。
ホームページ制作などのお仕事に関するご依頼やご相談は、運営者情報のお問い合わせフォームかSNSのDMにて宜しくお願いします。

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

スムーススクロール

どうも、ダイチです。

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

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

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

目次

スムーススクロールとは

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

Image from Gyazo

何も仕掛けがないと下のGif画像のように一瞬でパッと遷移するわけですが、ユーザーは「移動した」という実感がありません。

Image from Gyazo

こうなると、ページ内に用意したコンテンツも見られないことになるため、サイトの離脱、直帰率が上がってしまう可能性があります。

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

そういう意味でも、縦スクロールがあるWebサイトの多くに導入されているのではないかと思っています。

※ちなみに「スムーズスクロール」と読むこともありますが意味は同じです。(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>
    <section id="section1" class="section">section1</section>
    <section id="section2" class="section">section2</section>
    <section id="section3" class="section">section3</section>
    <section id="section4" class="section">section4</section>
    <section id="section5" class="section">section5</section>
    <p class="back-btn"><a href="#">Topに戻る</a></p>
  </main>

CSS

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

.header-inner {
  position: fixed;
  top: 0;
  display: flex;
  justify-content: space-around;
  align-items: center;
  width: 100%;
  height: 80px;
  background-color: rgb(31, 44, 223);
}

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

.header-inner li:hover {
  background-color: rgb(122, 130, 243);
}

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

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

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

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

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

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

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

.back-btn a:hover {
  background-color: rgb(122, 130, 243);
}

jQueryコード全体

$(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 が#から始まる要素を取得する」という記述になります。

こちらの記事で詳しく解説されていました。

WEMO
[href^=#]とはなんぞや。ページ内リンクをスムーススクロールさせる時に記述しているあれ | WEMO
[href^=#]とはなんぞや。ページ内リンクをスムーススクロールさせる時に記述しているあれ | WEMOページ内部でのリンク(目次など)を押した時に、スクロールアニメーションでリンク先まで移動するスクリプトありますよね。ソースコードをググるとコピペで使えるコードが...

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

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

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

あわせて読みたい
属性セレクター - CSS: カスケーディングスタイルシート | MDNCSS の属性セレクター (attribute selector) は、指定された属性が存在するかどうかや、その値に基づいて要素を選択します。

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

ここから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の基礎知識なので知っておかないといけないですね。

あわせて読みたい
比較演算子 | MDNJavaScript には、厳密な比較と型変換の比較の両方があります。厳密な比較 (例: ===) は、オペランドが同じ型で、内容も一致している場合にのみ真になります。もっとよく使...

? ‘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条件 (三項) 演算子は JavaScript では唯一の、3 つのオペランドをとる演算子です。条件に続いて疑問符 (?)、そして条件が真値であった場合に実行する式、コロン (:) が続...

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

var position = target.offset().top;

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

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

ということです。

flatFlag
jQueryのoffset() で表示位置の取得と要素の移動jQueryで要素の位置を取得したり移動させるには offset() を使います。位置がズレたり、undefinedエラーになる場合の対処法もご紹介します。

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

var speed = 500;

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

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

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

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

  1. href = クリックしたaタグに記述されているidの中身(#×× or # or 空白)
  2. target = 変数hrefのif式の結果(#××かhtml)
  3. position = 変数targetのドキュメント上部からの距離
  4. 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実装まとめ

クリックしたaタグのhrefの中身を取得

中身が#のみ、もしくは空白だったら高さ0、#idが取得できたらページトップからの位置(高さ)を取得

現在位置から取得した高さ(0〜)まで500秒かけて移動

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

まとめ

いかがでしたでしょうか?

このスムーススクロールのコードをググると、実はほぼ同じ内容が紹介されていたりします。

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

移動高さを細かく指定したり、別ページからの遷移時に指定したりと、まだまだ応用が必要なパターンはありますので別の機会でまとめます(たぶん)

また、スクロール繋がりで、画面領域に入ったら要素をふわっと表示させる実装方法もまとめていますので、気になるかたは是非。

あわせて読みたい
スクロールしたらふわっと表示されるアニメーションの実装方法(コピペ可)
スクロールしたらふわっと表示されるアニメーションの実装方法(コピペ可)どうも、ダイチです。今回はポートフォリオでもよく見かける、スクロールに合わせてテキストや画像がフワッと表示されるアニメーションの実装方法についてまとめました...

それでは今回はこのへんで!

スムーススクロール

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!

この記事を書いた人

異業種で仕事をしながら、副業でWeb制作をしているアラサーリーマンです。
日々の勉強の記録や、お役立ち情報を発信していきます。
ホームページ制作などのお仕事に関するご依頼やご相談は、運営者情報のお問い合わせフォームかSNSのDMにて宜しくお願いします。

コメント

コメントする

CAPTCHA


目次
閉じる