【jQuery】スムーススクロールをマスターする(ページ内リンク、ページの先頭に戻る)

  • URLをコピーしました!
目次

スムーススクロールとは(完成コード)

今回は「スムーススクロール」を解説します。

スムーススクロールとは、ページ内でリンクやボタンをタップした時に、該当の箇所まで滑らかに移動する動きのことです。

その名の通り、スムースにスクロールします!笑

HTMLだけでもリンクの遷移自体の実装は可能ですが、なめらかにスクロールされないので、jQueryを使用してなめらかにします。

かわてつ

なめらかに移動させるだけで、サイト全体の印象が全く変わってきます!
簡単に実装できる内容なのでぜひ見てくださいね!

こちらが完成コードになります!

ヘッダーの「セク1」「セク2」「セク3」をクリックして挙動を確認してみてください!

固定されているヘッダーの高さを考慮してセクションの移動がなめらかにされていると思います!

・右側Resultタブの「Run Pen」ボタンをクリック後、ヘッダーのリンクをタップして挙動を確認してください!

・左側のHTML,CSS,JSタブをクリックすると、それぞれのコードが表示されます。

ご自身で使用される際は、headタグの記述やjQueryの読み込みは忘れないようにしましょう!

See the Pen スムーススクロール(スパキャリ) by teppei (@kawatetu) on CodePen.

jQueryを使用せずにCSSだけでもスムーススクロールは実装できますが、
速度や遷移先の位置の調整ができないので、jQueryで実装した方が無難です!

それでは簡単にコードの解説をしていきます!

コード解説

ページ内リンクのスムーススクロールを実装する上でのポイントは

①HTML,CSSでリンクと遷移先を設定する(href属性の記載と遷移先にidを付与)
②jQueryで動きをなめらかに&ヘッダーの高さを考慮した位置調整をする

この流れで実装していきます!

①HTML,CSSでリンクと遷移先を設定する(href属性の記載と遷移先にidを付与)

HTML

<header class="p-header">
  <h1 class="p-header__title">
    ヘッダー
  </h1>
  <div class="p-header__nav">
    <ul class="p-header__nav-lists">
      <li class="p-header__nav-list">
        <a href="#section1">セク1</a>
      </li>
      <li class="p-header__nav-list">
        <a href="#section2">セク2</a>
      </li>
      <li class="p-header__nav-list">
        <a href="#section3">セク3</a>
      </li>
    </ul>
  </div>
</header>

<p class="p-heading">
  今回はスムーススクロールを解説します!<br>ヘッダーのナビゲーション「セク1」〜「セク3」をクリックして、ページ内の動きを確認してください!
</p>

<section class="p-section1" id="section1">
  <div class="l-inner">
    <div class="p-section1__contents">
      <p class="p-section1__text">
        セクション1です。これはセクション1です。セクション1です。これはセクション1です。セクション1です。これはセクション1です。セクション1です。これはセクション1です。セクション1です。これはセクション1です。セクション1です。これはセクション1です。セクション1です。これはセクション1です。セクション1です。これはセクション1です。セクション1です。これはセクション1です。セクション1です。これはセクション1です。セクション1です。これはセクション1です。セクション1です。これはセクション1です。セクション1です。これはセクション1です。セクション1です。これはセクション1です。セクション1です。これはセクション1です。
      </p>
    </div>
  </div>
</section>

<section class="p-section2" id="section2">
  <div class="l-inner">
    <div class="p-section1__contents">
      <p class="p-section1__text">
        セクション2です。これはセクション2です。セクション2です。これはセクション2です。セクション2です。これはセクション2です。セクション2です。これはセクション2です。セクション2です。これはセクション2です。セクション2です。これはセクション2です。セクション2です。これはセクション2です。セクション2です。これはセクション2です。セクション2です。これはセクション2です。セクション2です。これはセクション2です。セクション2です。これはセクション2です。セクション2です。これはセクション2です。セクション2です。これはセクション2です。セクション2です。これはセクション2です。セクション2です。これはセクション2です。
      </p>
    </div>
  </div>
</section>

<section class="p-section3" id="section3">
  <div class="l-inner">
    <div class="p-section1__contents">
      <p class="p-section1__text">
        セクション3です。これはセクション3です。セクション3です。これはセクション3です。セクション3です。これはセクション3です。セクション3です。これはセクション3です。セクション3です。これはセクション3です。セクション3です。これはセクション3です。セクション3です。これはセクション3です。セクション3です。これはセクション3です。セクション3です。これはセクション3です。セクション3です。これはセクション3です。セクション3です。これはセクション3です。セクション3です。これはセクション3です。セクション3です。これはセクション3です。セクション3です。これはセクション3です。セクション3です。これはセクション3です。
      </p>
    </div>
  </div>
</section>

CSS

*,
::before,
::after {
  box-sizing: border-box;
  min-inline-size: 0;
  border-style: solid;
  border-width: 0;
}

.p-heading {
  height: 100px;
  color: #333333;
  margin-top: 50px;
  font-weight: bold;
  font-size: 18px;
  padding: 30px 20px;
}

.p-header {
  height: 50px;
  background-color: #1e73be;
  color: #FFFFFF;
  padding: 0 20px;
  width: 100%;
  position: fixed;
  z-index: 1;
  display: flex;
  top: 0;
  justify-content: space-between;
}

.p-header__title {
  font-size: 16px;
  line-height: 50px;
}

.p-header__nav-lists {
  display: flex;
  gap: 0 20px;
}
.p-header__nav-list {
  line-height: 50px;
}

.p-header__nav-list a {
  text-decoration: none;
  color: inherit;
}

.p-header__nav-list a:hover {
  opacity: 0.7;
  transition: .3s;
  cursor: pointer;
}

.l-inner {
  width: 100%;
  padding: 0 20px;
  margin-right: auto;
  margin-left: auto;
}

.p-section1 {
  height: 500px;
  margin-top: 50px;
  background: orange;
  padding-top: 30px;
}

.p-section2 {
  height: 500px;
  background: greenyellow;
  padding-top: 30px;
}
.p-section3 {
  height: 1000px;
  background: pink;
  padding-top: 30px;
}

今回はシンプルにヘッダーとセクション3つを用意しました!
ヘッダーは固定しています。

ポイントとしては、

ヘッダーのナビゲーションリンク(セク1〜セク3)のhref属性にぞれぞれ#section1〜#section3を振っています。
(href=”#section1″ の箇所ですね!)

次に、遷移したい箇所にhref属性で付与した「#以降の文字」をidで付与します!
(今回の例で言うと、id=”section1″の箇所です!)

idを付与する際は「#」は不要なので、注意してください!

この記述時点での挙動は以下のようになっています。

href属性の記載と、それに紐づける形でidを付与すると遷移の実装自体はすぐ終わります。

しかし、現状ではヘッダーの高さ分ずれているのとなめらかに移動しないので見る側からしたらストレスですね。

ここからjQueryで位置と速度の調整をします。

②jQueryで動きをなめらかに&ヘッダーの高さを考慮した位置調整をする

位置と速度の調整するためのコードは以下です。

JS

jQuery(function ($) {
  $(document).on('click', 'a[href*="#"]', function () {
    let time = 500;
    let header = $('header').innerHeight();
    let target = $(this.hash);
    if (!target.length) return;
    let targetH = target.offset().top - header;
    $('html,body').animate({ scrollTop: targetH }, time, 'swing');
    return false;
  });
});

順番に解説していくと、

2行目
リンク(href属性に#がついているもの)をクリックした時の挙動の指示出しをしています。

3行目〜5行目
移動する時間(今回は0.5秒)、ヘッダーの高さ(innerHeightで高さを取得)、クリックした要素の値(hash)をそれぞれ取得して変数として入れています。(変数の名前はなんでも良いです。)

7,8行目
ヘッダーの高さ分を差し引いた位置を取得し、
その位置まで指定した時間でなめらかにスクロールします。
{ scrollTop: targetH }が「targetHまでスクロールする」という指示で、
timeが移動時間、swingは移動の仕方です(初めはゆっくり動きながらスクロールする)。

これにより、スムーススクロールでページ内リンクの実装ができました!

実践課題(ページ先頭に戻るボタンでスムーススクロール)

実践として、スムーススクロールでページの先頭へ戻る実装をしてみてください!

このような動きです!

下記のポイントを踏まえて実装してください!

・ヘッダーの高さ分スクロールしたら、右下に「トップへ戻る」ボタンが出現する(最初は非表示)
・「トップへ戻る」ボタンをクリックするとなめらかにページの先頭へ戻る
・先頭に戻ると「トップへ戻る」ボタンは非表示になる。

今まで解説したコードをコピペして、追加実装してください!

実践課題サンプルコード(解答)

See the Pen スムーススクロール(先頭へ戻るボタン追加) by teppei (@kawatetu) on CodePen.

追加したコードと解説

追加したコードのみ記載します!

HTML

<button class="p-top-btn js-scroll-btn">TOPへ</button>

CSS

.p-top-btn {
  position: fixed;
  bottom: 20px;
  right: 20px;
  background: #1e73be;
  display: none;
  padding: 20px;
  color: #fff;
  text-decoration: none;
}

.p-top-btn:hover {
  opacity: 0.7;
  transition: .3s;
  cursor: pointer;
}

JS

$(".js-scroll-btn").click(function () {
    let time = 500;
    $('html, body').animate({ scrollTop: 0 }, time , 'swing');
});

$(window).scroll(function () {
    let header = $('header').innerHeight();
    if ($(window).scrollTop() > header) {
      $('.js-scroll-btn').fadeIn();
    } else {
      $('.js-scroll-btn').fadeOut();
}

HTMLでボタンを設置し、CSSで右下に固定しています。
display: none;を指定して最初は非表示にします。

3行目
scrollTop: 0 で遷移先の位置を先頭にしています。ここのscrollTopは遷移先の位置を示しています。

7〜9行目
7行目でヘッダーの高さを取得します。
if文を使用して、ヘッダーの高さよりスクロールされた場合はトップへ戻るボタンを表示し、それ以外の場合はトップへ戻るボタンを表示させます。

以上です!
ここまで読んでいただきありがとうございました!

不明点やご質問がありましたら、私のXまでDMをしてください!

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

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次