ページリンク付きのアンカーリンクに対応したjQueryのスムーススクロール
ページ内のアンカーリンク(#link01のようにページ内のIDの場所を指定して移動させるリンク)のとき、
ページ内での移動であることがユーザーにわかりやすくなるため、
スムーススクロールを使う機会はとても多いと思います。
ただ、Wordpressなどでメニューを管理する場合で、
リンクにアンカーリンクをつけたい場合、
ページ外からのリンクも行う必要があるために、
以下のように、ページのリンク(URL)+アンカーリンクという形でリンク先を指定しなくてはならなくなることがあると思います。
1 | <a href=/example/example-second/#link01”>ナビメニュー</a> |
この場合、通常よく使われる、以下の様なjQueryのコードでは、
同じページ内からアクセスしても、
スムーススクロールではなく元のリンクの動きになってしまいます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | $(function(){ $('a[href^=#]').not(".noScroll").click(function() { var speed = 400, href = $(this).attr("href"), target = $(href == "#" || href == "" ? 'html' : href), position = target.offset().top, body = 'body', userAgent = window.navigator.userAgent.toLowerCase(); if (userAgent.indexOf('msie') > -1 || userAgent.indexOf('trident') > -1 || userAgent.indexOf("firefox") > -1 ) { /*IE8.9.10.11*/ body = 'html'; } $(body).animate({ scrollTop: position }, speed, 'swing'); return false; }); }); |
そこで、今回はページヘのリンクとアンカーリングが両方付いている場合でも、
同じページ上のアンカーリンクであった場合に、
スムーススクロールとしての動きを実装するようにしたコードを考えてみました。
↓こちらがデモです
jQueryコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | $(function(){ $('a[href*=#], area[href*=#]').not(".noScroll").click(function() { var speed = 400, // ミリ秒(この値を変えるとスピードが変わる) href = $(this).prop("href"), //リンク先を絶対パスとして取得 hrefPageUrl = href.split("#")[0], //リンク先を絶対パスについて、#より前のURLを取得 currentUrl = location.href, //現在のページの絶対パスを取得 currentUrl = currentUrl.split("#")[0]; //現在のページの絶対パスについて、#より前のURLを取得 //#より前の絶対パスが、リンク先と現在のページで同じだったらスムーススクロールを実行 if(hrefPageUrl == currentUrl){ //リンク先の#からあとの値を取得 href = href.split("#"); href = href.pop(); href = "#" + href; //スムースクロールの実装 var target = $(href == "#" || href == "" ? 'html' : href), position = target.offset().top, //targetの位置を取得 body = 'body', userAgent = window.navigator.userAgent.toLowerCase(); if (userAgent.indexOf('msie') > -1 || userAgent.indexOf('trident') > -1 || userAgent.indexOf("firefox") > -1 ) { /*IE8.9.10.11*/ body = 'html'; } $(body).animate({ scrollTop: position }, speed, 'swing', function() { //スムーススクロールを行ったあとに、アドレスを変更(アドレスを変えたくない場合はここを削除) if(href != "#top" && href !="#") { location.href = href; } }); return false; } }); }); |
仕組みとしては、
リンク先のURLと現在のページのURLを比較して、
#より前のアドレスが同じであればスムーススクロールを実行するようにしています。
ポイントは、リンク先を.attr(“href”)ではなく、.prop(“href”)で取得して、現在のURLと比較している点です。
.attr(“href”)でリンク先を取得した場合は、hrefに設定されている値がそのまま取得されますが、
.prop(“href”)でリンク先を取得した場合は、絶対パスとしてURLを取得することができます。
hrefの指定は、相対パス、絶対パス、ルート相対パスなど、様々な指定方法があります。
そのままの値だとムラが出てきてしまう可能性があり、
hrefの値と現在のページのURLと比較する場合に支障が出てくることがあります。
しかし、.prop(“href”)を使って、必ず絶対パスとしてhrefの値を取得すれば、そのムラを防ぐことができます。
是非ご活用下さい。
参考にさせていただいたサイト
【JavaScript】a要素のhrefから絶対パスの取得 at softelメモ
JavaScript split 文字列を指定文字で抜き出す
Author Profile
NINOMIYA
Webデザイナー兼コーダー出身のフロントエンド開発者です。 UXデザインやチーム開発の効率化など、勉強中です。
SHARE