jQuery:smoothscrollを作ってみた 2015.03.17
初心者向けはじめに
最近、こつこつとjQueryを学習中です。
まだまだぼんやりと見えてきた段階で、当ブログに載せる内容もまだ定まらない状況です。
とりあえず、ごくごく簡単な「smoothscroll」を作ってみたので、紹介します。
1 2 3 4 5 6 7 8 9 |
$(function(){ $("[href^='#']").click(function(event){ var scrollSpeed = 1000; var targetId = $(this).attr('href'); var targetY = $(targetId).offset().top; event.preventDefault(); $('html,body').animate({scrollTop: targetY},scrollSpeed); }); }); |
INDEX
- 属性セレクターとclickイベント
- event.preventDefault
- 変数を定義
- アニメーションさせる
1.属性セレクターとclickイベント
1 2 3 4 |
$(function(){ $("[href^='#']").click(function(event){ //href属性が#から始まる要素をクリックするとイベントが発生 }); }); |
まず、対象をjQueryObjectにするために、セレクターを使ってドキュメントから拾ってきます。
今回の場合は、対象はa要素です。
もっと言うと、href属性が#から始まっているa要素です。
<a href=”http://google.co.jp/”>というような、アンカーリンクではない普通のリンクは対象外とします。(詳しくは後述)
そのため、セレクターは $(‘a’) ではなく、$(“[href^=’#’]”)です。
※ [属性名^=’値’] で、 指定した値から始まる属性を含む要素 というように選択できます。
また、 $(“[href^=’#’]”) をクリックした時に処理を実行したいので、clickイベントを生成します。
後工程で、ブラウザのアンカーリンク動作をなくしたいので、引数としてeventを渡します。
※jQueryObject.click(function(){イベントハンドラ})
イベントハンドラは、イベント内容のことです。
2.event.preventDefault
1 2 3 4 5 |
$(function(){ $("[href^='#']").click(function(event){ event.preventDefault(); //ブラウザの動作を無効化 }); }); |
先ほど渡した引数 event に対して、preventDefault と設定します。
これで、ブラウザのリンク動作を無効化します。
つまり、アンカーリンクをクリックしても何も起きない、という状態になります。
※サンプル(googleへのリンクは機能しています)
前述したa要素をセレクターとせずに、#から始まるhref属性を持つ要素をセレクターとしたのには、このためです。
この後、アンカーリンク(#から始まるhref属性を持つ要素)にはアニメーションメソッドで、アニメーションさせますが、リンクをクリックしたらウィンドウやタブを開くという動作は記述しません。
簡単に言えば、a要素をセレクターにしてしまうと、ページ内リンク以外の機能がすべてなくなってしまうから、です。
※eventObject.preventDefault は、ブラウザの持つ動作を無効にします。
eventObject には自由な値が入りますが、event や e とすることが多いです。
3.変数を定義
1 2 3 4 5 6 7 8 |
$(function(){ $("[href^='#']").click(function(event){ var scrollSpeed = 1000; //スクロールスピード var targetId = $(this).attr('href'); //クリックした要素のhref属性の値を取得し、targetIdとして定義 var targetY = $(targetId).offset().top; //targetIdの要素のY座標を取得し、targetYとして定義 event.preventDefault(); }); }); |
説明上、順番が遅くなりましたがここで変数を定義します。
※変数は、名前付きの箱のようなものです。様々な文字列を入れることができ、非常に便利です。
var 変数名; で定義し、変数名 = 入れる値; で中に入れます。
scrollSpeed は、アニメーションする速さ(ミリ秒)です。
targetId は、移動先のid属性が入ります。
ここでは、 $(this).attr(‘href’); と、クリックした要素のhref属性を取得して入れています。
移動させるa要素 <a href=”#○○”> のhref属性の値と、移動先のdiv要素 <div id=”○○”> のid属性が同一である、というのがポイントです。
※$(this) の this は特殊な変数です。
その時々によって中に入っている値が変わるという変数で、この場合は [href^=’#’] が入っています。
その時々とは、つまりイベントが発生する時々、ということです。(この場合はクリックされた要素)
内部では色々な処理が行われているようですが、ここでは割愛します。
※jQueryObject.attr(‘属性名’) で、指定した要素の属性の値を取得することができます。
targetY は、移動先の要素のY座標が入ります。
変数targetId、つまり移動先の要素のidをセレクターとし、 .offset().top でY座標を取得しています。
※jQueryObject.offset().top で、指定した要素のY座標の値を取得できます。
.offset().left とすれば、y座標の値を取得します。
4.アニメーションさせる
1 2 3 4 5 6 7 8 9 |
$(function(){ $("[href^='#']").click(function(event){ var scrollSpeed = 1000; var targetId = $(this).attr('href'); var targetY = $(targetId).offset().top; event.preventDefault(); $('html,body').animate({scrollTop: targetY},scrollSpeed); //(body要素のY座標をtargetYにする)をscrollSpeed(ミリ秒)でアニメーション }); }); |
必要なものはすべて揃いましたので、あとはアニメーションさせて完了です。
まず何をアニメーションさせるか、ですが、これはbody要素のY座標が対象となります。
通常、ページを開いた直後はbodyのY座標は0ですが、スクロールする度に、その値は増えていきます。
(例:<div id=”first”>→Y=100 <div id=”second”>→Y=600)
今回は、a要素をクリックした時に、アンカー先のid属性を持った要素のY座標の値へ変化していけばいい、というわけです。
なので、.animateメソッドを使って、body要素のY座標をアンカー先のY座標に変化させていくようにしました。
※scrollTop とはオブジェクトのY座標のことです。scrollLeft はX座標。
補足
ちなみに上記のコードはbody要素とhtml要素の両方を指定していますが、実はブラウザによってscrollTopのセレクタ要素が変わる場合があるようです。
(参考:jQuery:スムースなスクロール(後編))
ほとんどの場合、body要素でOKですが、一部のブラウザはhtml要素にしか反応しないようです。
そのため、両方指定しています。
しかし、両方指定することによる問題、というのもあるようです。
(参考:ページ内リンクへアニメーションで移動)
簡単に言ってしまえば、同じ処理が2回されるということですね。
もし、アニメーションが終わった後に、何か処理をしたい場合、それも2回実行されてしまう、ということです。
これを防ぐにはブラウザを判別するメソッド(関数)を作る、という方法があるようです。
(参考:jQuery 1.9 で $.browser が使えなくなってしまった対策)
詳しく解説するとまた長くなってしまうので、ここでは割愛します。
上記のスムーススクロールは、ほとんどのブラウザで問題なく動作しますし、アニメーション後に何かするということがない限り、使えるはずです。
参考
Thanks for reading to the end!!