ページ内のリンクをクリックしたときに、カチってページが切り替わるのってちょっとスマートじゃないですよね。ここでは、ページ内リンクをクリックしたときに、スーッとスクロールさせる方法をjQueryを使って実装していきます。
コンテンツ
ページ内リンクをスムーズにスクロールさせる方法
最初に完成したソースコードをご覧ください。
ボタンで表示を切り替えてご覧ください。
See the Pen smooth-scrolling by kenichi (@ken81) on CodePen.
「クリック」のところをクリックすると下へ移動し、「上へ」をクリックすると上に移動します。それが下記のコードです。
$(function(){ $('a[href^="#"]').click(function(){ var time = 500; var href= $(this).attr("href"); var target = $(href == "#" ? 'html' : href); var distance = target.offset().top; $("html, body").animate({scrollTop:distance}, time, "swing"); return false; }); });
ここでは、上記のコードをできるだけ細かく分解してお話したいと思います。
もしも、jQueryにあまり触れたことがないという方は、私がよく分からなかったときに教えてほしかった内容を記事にまとめてありますので下記もご参照ください。
click()
メソッド
$('セレクタ').click(function(){ //処理する内容 });
上記は、ひとつの公式のようなものです。clickメソッドといって、カッコの中「()」で指定した要素をクリックしたら波カッコ「{}」の中の処理をしてくださいというものです。
属性セレクタ[属性^="値"]
a[href^="#"]
という部分は、属性セレクタと言われるものです。「#
というキーワードから始まるhref
属性」を指定しています。つまり、id名がリンク先になったものという意味ですね。
この時点で「属性」というものが何なのか分からないという方は下記もご参照ください。
[A^=”B”] = 値が「B」で始まる「A」という属性を指定
この^
というのがポイントです。これがあるときは、「~から始まる」という意味になります。ない場合、単なるイコールになります。
[A=”B”] = 「B」という値を持つAという属性を指定
ここでは、a[href^="#"]
なので、「#で始まるアンカータグ」が指定されていることになります。
実はこれスタイルシートでも使えるってご存知でしたか?下記でスタイルシートのセレクタについていろいろ紹介しているので良かったらチェックしてみてください。
変数の宣言と値の代入var 変数 = 値;
var time = 500; var href= $(this).attr("href"); var target = $(href == "#" ? 'html' : href); var distance = target.offset().top;
上記の4行はすべて変数を宣言して代入しているところです。
var 変数 = 値;
これが出てきたら、変数を宣言して右側の値を代入していると思って下さい。
変数の名前は、任意で自由に決めることができます。
var time = 500;
これは後ほど、スクロールにかける時間を指定するところで使うのでtime
という変数に500(0.5秒)という値を代入しているところです。
$(this)
はイベントのきっかけとなる要素
var href= $(this).attr("href");
$(this)
はそのイベントのきっかけとなる要素を指すものなので、ここでは、$('a[href^="#"]')
とイコールになります。あくまでも「ここでは」の話ですよ。
$(this) = $(‘a[href^=”#”]’)
attrメソッド
$(this).attr("href");
これはattrメソッドです。
$(セレクタ).メソッド(メソッドの処理);
このパータンが出たら「メソッドだな」と思っておけば間違いないです。今回の場合は、
$(A).attr(“B”);
となっているので、「Aという要素のBという属性の値」という意味になります。つまりここでは、$(this).attr("href");
なので、「クリックされたアンカータグのhref属性の値(つまり、リンク先のURL)」という意味です。
話をまとめると、href
という変数にリンク先のURLの値を代入しているということになります。
三項演算子
var target = $(href == "#" ? 'html' : href);
左側はtarget
という変数です。この変数は、クリックしたときの目的地(リンク先)を指定するために設定した変数になります。右側の部分が少しややこしいですが、これは「三項演算子」と言います。
条件 ? TRUEの場合 : FALSEの場合
左の「条件」が当てはまる場合は「TRUEの場合」の処理となり、当てはまらない場合は「FALSEの場合」の処理をします。
つまり、ここではリンク先が#
だった場合(つまり、href="#"
の場合)は、html
をtarget
に代入、そうでない場合は、リンク先をそのままtarget
に代入するという意味です。href="#"
というのは、ページのトップ(一番上)へ移動するリンクを貼りたいときに使う値なのですが、これだとこの次に距離を測定するときに都合が悪いようなのです(ちょっと曖昧)。
トップからのタテの距離|$('要素').offset().top;
var distance = target.offset().top;
$('要素').offset().top;
は、ドキュメント(つまり、ページの一番上)から「要素」までのタテの距離です。今回は、変数target
が要素として指定されているので、ページの一番上から先ほど指定したリンク先となるid属性の要素までの距離ということになります。この距離の値が変数distance
に代入されます。
animateメソッド|$("要素").animate({ 動き } , 時間 , 速さ );
$("html, body").animate({scrollTop:distance}, time, "swing");
これはanimateメソッドと言われるものです。
$(“要素”).animate({プロパティ:”値” } , 時間 , 速さ );
これは「要素」を動かすメソッドです。どのように動かすかは、プロパティ:"値"
のところで指定します。カンマ区切り(,)で動きの「時間」と「速さ」を指定できます。
$("html, body").animate({scrollTop:distance}, time, "swing");
今回の場合、html要素、もしくはbody要素のスクロールの値(scrollTop)をdistance
の距離だけ、time
の時間をかけてswing
で移動させるという意味になります。ちょっと説明が分かりづらいですね。
リンク先への移動をキャンセルreturn false;
最後のreturn false;
というのは、クリックイベントを実行したときにクリックされたリンク先にページが移動してしまうのをキャンセルするための命令です。
今回、jQueryで動きを実装しているので、リンク先へページ内ジャンプさせる通常の動きをキャンセルしなければいけません。そのため最後に通常のリンク先への移動をキャンセルします。
はい、これですべての説明が終わりました。
最後に全体のソースコードをコメント付きで見てましょう。
$(function(){ $('a[href^="#"]').click(function(){ // 変数timeに500(0.5秒)を代入 var time = 500; // 変数hrefにリンク先の値を代入 var href= $(this).attr("href"); // href="#"の場合は変数targetにhtmlを、そうでない場合はリンク先の値を代入 var target = $(href == "#" ? 'html' : href); // 変数distanceにページの一番上からリンク先までの距離を代入 var distance = target.offset().top; // 変数distanceの値だけ上へ0.5秒かけてスクロールさせる $("html, body").animate({scrollTop:distance}, time, "swing"); // リンク先への移動をキャンセル return false; }); });
おわりに
スムーズなスクロールについて調べていると、よく下記のようなコードを見かけるのですが、これってどういう意味なんでしょうね。
var target = $(href == "#" || href == "" ? 'html' : href);
「#」からはじまるリンクに対するクリックイベントなのに、その中で「href=""
の場合」という条件があるのっておかしいと思いませんか。起こり得ない条件をわざわざ記入する必要性って何かあるのでしょうか?みんな同じコードを紹介しているのには、何か理由があるのでしょうか。ご存知の方がいたら教えてくださーい笑