書いて覚えるjQuery!「TOPに戻る」ボタン編

jQueryを使って、ページの右下に「TOPに戻る」ボタンを設置する方法を紹介します。その「TOPに戻る」ボタンは、クリックすることでページの上部にスクロールします。

また、ページの上部にスクロールするのをアニメーションにする方法や、ある程度スクロールしないと「TOPに戻る」ボタンが表示されないようにする方法なども紹介しています。

デモ

別ウィンドウで表示する場合は、こちらをクリックしてください。

「TOPに戻る」ボタン設置前の状態

単にテキストが並んでいるだけです。。。ソースは以下のようになっています。

HTMLファイル(index.html)

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <link rel="stylesheet" href="./style.css" type="text/css" />
    <script src="./jquery-2.1.4.min.js"></script>
    <script src="./base.js"></script>
  </head>
  <body>
    <div id="main">
      <p>ページの一番上までスクロールさせるテストです。 - 1行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 2行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 3行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 4行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 5行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 6行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 7行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 8行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 9行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 10行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 11行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 12行目</p>
    </div>
  </body>
</html>

CSSファイル(style.css)

#main p {
  margin-bottom: 50px;  /* テキストとテキストの間を広くしています。 */
}

JSファイル(base.js)

JSファイルはまだ何も処理を書いていません。

「TOPに戻る」ボタンの作成

それでは、本編の「TOPに戻る」ボタンの作成に進みます。ここでは、

  1. 「TOPに戻る」ボタンを設置する
  2. 「TOPに戻る」ボタンに動きをつける

というステップで進めていきます。

「TOPに戻る」ボタンを設置する

「TOPに戻る」ボタンを設置します。この時点ではデザインだけで、ボタンをクリックしても何も起こりません。

まずはHTMLファイルを編集し、ボタンを設置します。</body>の直前に、以下のコードを追加します。

<div id="scroll_to_top" class="button">
  <p>TOPに戻る</p>
</div>

これで、ページの一番下に「TOPに戻る」というテキストが表示されるようになりました。

次は、CSSファイルを編集し「TOPに戻る」ボタンのデザインを変えます。変更点は以下の3つです。

  • カーソルを合わせた時に、カーソルが指の形になるようにする。
  • 常にページの右下に表示されるように固定します。
  • 見た目をテキストからボタンに変える。

CSSに追加する内容は以下の通りです。

#scroll_to_top {
  /* 「TOPに戻る」ボタンにカーソルを載せた時に、
  カーソルが指のマークになるようにしています。 */
  cursor: pointer;

  /* 常にページの右下に表示されるように固定します。 */
  position: fixed;  /* 位置を固定させます。 */
  right: 20px;      /* 画面の右橋から20px空けます。 */
  bottom: 20px;     /* 画面の下端から20px空けます。 */
}
#scroll_to_top.button {
  /* 「TOPに戻る」ボタンのデザインを整えています。 */
  padding: 0 15px;
  font-size: 15px;
  display: inline-block;
  border: 1px solid #999;
  border-radius: 1em;
  background-color: #eee;
}

ちなみに、#scroll_to_top.button {の中は、タグのidにscroll_to_topが指定され、さらにclassにbuttonが指定されているときに適用されるスタイルを決めています。

ここで指定されているスタイルは「見た目をテキストからボタンに変える」です。そのため、classからbuttonを外すと、「TOPに戻る」ボタンの見た目がボタンからテキストに戻ります。

「TOPに戻る」ボタンに動きをつける

ボタンのデザインを整えたら、後はボタンがクリックされたときの動きを決めるだけです。JSファイルを以下のようにします。

$(function() {
  // 「TOPに戻る」ボタンがクリックされた時の動きを指定します。
  $("#scroll_to_top").click(function() {
    // ページの一番上までスクロールさせます。
    $('body, html').scrollTop(0);
  });
});

これで、ページの一番上までスクロールさせる、「TOPに戻る」ボタンを設置できました!

「TOPに戻る」ボタンのソース

HTMLファイル(index.html)

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <link rel="stylesheet" href="./style.css" type="text/css" />
    <script src="./jquery-2.1.4.min.js"></script>
    <script src="./base.js"></script>
  </head>
  <body>
    <div id="main">
      <p>ページの一番上までスクロールさせるテストです。 - 1行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 2行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 3行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 4行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 5行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 6行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 7行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 8行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 9行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 10行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 11行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 12行目</p>
    </div>

    <div id="scroll_to_top" class="button">
      <p>TOPに戻る</p>
    </div>
  </body>
</html>

CSSファイル(style.css)

#main p {
  margin-bottom: 50px;  /* テキストとテキストの間を広くしています。 */
}
#scroll_to_top {
  /* 「TOPに戻る」ボタンにカーソルを載せた時に、
  カーソルが指のマークになるようにしています。 */
  cursor: pointer;

  /* 常にページの右下に表示されるように固定します。 */
  position: fixed;  /* 位置を固定させます。 */
  right: 20px;      /* 画面の右橋から20px空けます。 */
  bottom: 20px;     /* 画面の下端から20px空けます。 */
}
#scroll_to_top.button {
  /* 「TOPに戻る」ボタンのデザインを整えています。 */
  padding: 0 15px;
  font-size: 15px;
  display: inline-block;
  border: 1px solid #999;
  border-radius: 1em;
  background-color: #eee;
}

JSファイル(base.js)

$(function() {
  // 「TOPに戻る」ボタンがクリックされた時の動きを指定します。
  $("#scroll_to_top").click(function() {
    // ページの一番上までスクロールさせます。
    $('body, html').scrollTop(0);
  });
});

カスタマイズ

ここでは、「TOPに戻る」ボタンの動きなどをカスタマイズしてみます。

アニメーションを追加する

現時点の「TOPに戻る」は、ボタンを押すと一瞬でページのトップまで移動します。ここにアニメーションを付けて、もっとスムーズにスクロールするようにしてみます。

アニメーションは、jQueryのanimateメソッドを利用します。animateメソッドを使うと、引数で指定したスタイルにアニメーションをさせながら変化させることができます。

例えば、$('#scroll_to_top').animate({fontSize: '28px'}, 500);とすると、「TOPに戻る」ボタンの文字の大きさを、アニメーションさせながら28pxにすることができます。また、そのアニメーション終了までの時間を0.5秒(500ミリ秒)としています。この500を大きくするとアニメーション終了までの時間が長くなるので、動きがゆっくりになっていきます。

それでは、「TOPに戻る」ボタンをクリックしたときに、アニメーションさせるようにするコードです。JSファイルの、「TOPに戻る」がクリックされたときのコードを以下のように書き換えます。

  $("#scroll_to_top").click(function() {
    // ページの一番上まで、アニメーション付きでスクロールさせます。
    // アニメーションの時間は300ミリ秒で、一定の速度(linear)で動かします。
    $('body, html').animate({scrollTop: 0}, 300, 'linear');
  });

上記コードでは、「TOPに戻る」ボタンが押された時に、300ミリ秒かけてscrollTopを0(ページの一番上に戻る)にしています。また、linearを指定していることで、アニメーションは一定の速度で動きます。

ある程度スクロールさせたら「TOPに戻る」を表示する

常に表示されている「TOPに戻る」ボタンを、最初は隠れていて、ある程度スクロールしたら表示されるように改良してみます。ある程度スクロールの「ある程度」は、ブラウザの画面分スクロールしたらにします。

この改良にあたって、まずはページがスクロールされたら何かをするというところから作ってみます。それは、JSファイルの$(function() {の中に、以下のようなコードを記述すれば実現できます。

$(function() {
  // 省略...

  $(window).scroll(function() {
    // ページがスクロールした時の処理を記述します。
    console.log('foo');
  });
});

上記コードだと、ページをスクロールさせる度に、ログに「foo」という文字列を出力しています。

これをふまえて、ある程度ページをスクロールしたときに「TOPに戻る」ボタンを表示させるようにしてみます。

$(function() {
  // 省略...
  $(window).scroll(function() {
    // 「TOPに戻る」ボタンを取得します。
    var $toTopButton = $('#scroll_to_top');

    // 縦にどれだけスクロールしたかを取得します。
    var scrollTop = $(this).scrollTop();

    // ウィンドウの縦幅を取得します。
    var windowHeight = $(this).height();

    if (scrollTop >= windowHeight) {
      // ウィンドウの縦幅以上にスクロールしていた場合、
      // 「TOPに戻る」ボタンを表示します。
      $toTopButton.show();
    } else {
      // ウィンドウの縦幅以上にスクロールしていない場合、
      // 「TOPに戻る」ボタンを隠します。
      $toTopButton.hide();
    }
  });
});

上記コードでは、条件によって「TOPに戻る」ボタンを表示したり(showメソッド)、非表示にしたり(hideメソッド)変化させています。

その変化させる条件は、縦にスクロールした距離が、ブラウザの縦幅よりも長いかどうかです。長い場合は「TOPに戻る」ボタンを表示し、短い場合は「TOPに戻る」ボタンを非表示にしています。

これで、ページをある程度スクロールさせたら「TOPに戻る」ボタンが表示されるようになりました。

リサイズなどに対応させる

スクロールだけではなく、例えばリサイズしたときなどにも「TOPに戻る」ボタンの表示・非表示を変えたいとします。その場合は、以下のように、$(window).resizeなどに、$(window).scrollと同じコードを書けば実現できます。

$(window).scroll(function () {
  // ある程度スクロールさせたら「TOPに戻る」ボタンを表示するコード
});

$(window).resize(function () {
  // (面倒だけれども)scrollで書いたのと全く同じコードを書く。
});

ただ、全く同じコードを書いてしまうと保守性などで問題がでてきます。例えば$(window).scrollに記述したコードを1箇所修正するだけで、resizeの同じ部分も修正する必要が生まれてしまいます。

これを解決するために、関数を使いまわせるようにしてみます。

まずは、変数「changeButtonState」に「ある程度スクロールしたら「TOPに戻る」ボタンを表示する」関数を代入しています。なお、「ある程度スクロールしたら「TOPに戻る」ボタンを表示する」関数は、$(window).scrollのときに作成したのとほとんど変わりません。変更したのは、thisをwindowに変更した程度です。

  // 関数を変数「changeButtonState」に入れておきます。
  var changeButtonState = function() {
    // 「TOPに戻る」ボタンを取得します。
    var $toTopButton = $('#scroll_to_top');

    // 縦にどれだけスクロールしたかを取得します。
    var scrollTop = $(window).scrollTop();

    // ウィンドウの縦幅を取得します。
    var windowHeight = $(window).height();

    if (scrollTop >= windowHeight) {
      // ウィンドウの縦幅以上にスクロールしていた場合、
      // 「TOPに戻る」ボタンを表示します。
      $toTopButton.show();
    } else {
      // ウィンドウの縦幅以上にスクロールしていない場合、
      // 「TOPに戻る」ボタンを隠します。
      $toTopButton.hide();
    }
  }

関数を変数に代入したら、後は好きなイベントを契機にその関数が実行されるようにするだけです。例えば、ウィンドウがスクロール・ロード・リサイズされたときに、「TOPに戻る」ボタンの表示非表示を切り替えるには以下のようにします。

  // 関数を変数「changeButtonState」に入れておきます。
  var changeButtonState = function() {
    // 省略...
  }

  // ウィンドウをスクロール・ロード・リサイズしたときを契機に、
  // 「TOPに戻る】ボタンの表示・非表示を変更します。
  $(window).scroll(changeButtonState)
           .load(changeButtonState)
           .resize(changeButtonState);

ページの下端に到達したら「TOPに戻る」ボタンを表示する

現段階では、ブラウザの画面分スクロールしたら「TOPに戻る」ボタンを表示しています。言い換えると、ブラウザの画面分スクロールできる余地がない場合、「TOPに戻る」ボタンは表示されることはなくなってしまいます。

それを回避するために、ページの下端に到達したら「TOPに戻る」ボタンを表示するようにしてみます。

修正方法は、「ブラウザの画面分スクロールしたら」という判定をしていた「if (scrollTop >= windowHeight) {」を、以下のように変更するだけです。

--- before.js   2015-06-24 13:17:17.000000000 +0900
+++ after.js    2015-06-24 13:16:48.000000000 +0900
@@ -17,8 +17,10 @@
     // ウィンドウの縦幅を取得します。
     var windowHeight = $(window).height();

-    if (scrollTop >= windowHeight) {
-      // ウィンドウの縦幅以上にスクロールしていた場合、
+    if (scrollTop >= windowHeight
+        || ($(document).height() - windowHeight) <= scrollTop) {
+      // ウィンドウの縦幅以上にスクロールしていた、
+      // またはページの下端に達していた場合、
       // 「TOPに戻る」ボタンを表示します。
       $toTopButton.show();
     } else {

「TOPに戻る」ボタンを画像にする。

「TOPに戻る」ボタンを画像にしたい場合は、idに「scroll_to_top」を指定したdivタグの、中身のpタグをimgタグに変更するだけです。また、同divタグのclassに指定していた「button」は削除し、枠線などのデザインを消しています。

    <div id="scroll_to_top">
      <img src="./totop.png" width="64" height="64" alt="TOPに戻る" />
    </div>

デモ

こちらをクリックすると、別ウィンドウで動作を確認できます。

カスタマイズしたバージョンのソース

カスタマイズしたバージョンの、HTMLとJSファイルを載せておきます。

HTMLファイル

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <link rel="stylesheet" href="./style.css" type="text/css" />
    <script src="./jquery-2.1.4.min.js"></script>
    <script src="./base.js"></script>
  </head>
  <body>
    <div id="main">
      <p>ページの一番上までスクロールさせるテストです。 - 1行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 2行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 3行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 4行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 5行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 6行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 7行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 8行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 9行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 10行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 11行目</p>
      <p>ページの一番上までスクロールさせるテストです。 - 12行目</p>
    </div>

    <div id="scroll_to_top">
      <img src="./totop.png" width="64" height="64" alt="TOPに戻る" />
    </div>
  </body>
</html>

JSファイル

$(function() {
  // 「TOPに戻る」ボタンがクリックされた時の動きを指定します。
  $("#scroll_to_top").click(function() {
    // ページの一番上まで、アニメーション付きでスクロールさせます。
    // アニメーションの時間は300ミリ秒で、一定の速度(linear)で動かします。
    $('body, html').animate({scrollTop: 0}, 300, 'linear');
  });

  // 関数を変数「changeButtonState」に入れておきます。
  var changeButtonState = function() {
    // 「TOPに戻る」ボタンを取得します。
    var $toTopButton = $('#scroll_to_top');

    // 縦にどれだけスクロールしたかを取得します。
    var scrollTop = $(window).scrollTop();

    // ウィンドウの縦幅を取得します。
    var windowHeight = $(window).height();

    if (scrollTop >= windowHeight
        || ($(document).height() - windowHeight) <= scrollTop) {
      // ウィンドウの縦幅以上にスクロールしていた、
      // またはページの下端に達していた場合、
      // 「TOPに戻る」ボタンを表示します。
      $toTopButton.show();
    } else {
      // ウィンドウの縦幅以上にスクロールしていない場合、
      // 「TOPに戻る」ボタンを隠します。
      $toTopButton.hide();
    }
  }

  // ウィンドウをスクロール・ロード・リサイズしたときを契機に、
  // 「TOPに戻る】ボタンの表示・非表示を変更します。
  $(window).scroll(changeButtonState)
           .load(changeButtonState)
           .resize(changeButtonState);
});

この記事が役に立った場合、シェアしていただけると励みになります!!