【jQuery】絶対パスのリンクでも
スムーススクロールさせるコードと主な注意点
今までに何度か、スムーススクロールについて解説をしてきました。
通常のサイトや使い方であれば今までの分で多くは対処できるのですが、1点だけ今までのコード分では対処できないケースがあり、絶対パスでリンクを書いていると、うまく動作してくれません。
とはいえ、サイト内リンクをそもそも絶対パスで書くのか?という疑問を持つ方もいるかもしれませんが、ケースバイケースで、絶対パスを使って構築する事もあり、そういう場合、今までの解説だけでは滑らかにスクロールしてくれません。
特にWordPressなどで、リンクを吐き出すと絶対パスで書き出されたりする事もあり、そういうケースでは以前のコードだとうまく動かないことになるため、今回はそんな絶対パスで記述した場合でもスムーススクロールを動作するためのコードの書き方についてまとめてみたいと思います。
相対パスと絶対パスのリンクとスムーススクロールをおさらい
スムーススクロールの基本をおさらいといきたいところですが、過去に解説したりもしていたので、詳細はそちらも合わせて確認いただければと思います。
- jQueryでページ内リンクをスムーススクロールにする設定とコード
- 以前に、スムーススクロールをCSSだけで設定する方法について解説しましたが、今回はCSSではなくjQueryを使って、ページ内リンクをクリックした際に...
過去のこの解説だと、サイト内リンクを書くときに相対パスで書く解説になっています。というのも、一般的なサイト制作であれば、サイト内のアンカーリンクに絶対パスを使うシーンというのはあまり多くなく、相対パスで書く事が多いためです。
しかしながら、相対パスで書かれたものは正常に動作しますが、絶対パスで#付きのアンカーリンクで書かれた場合は、スムーススクロールとならずにデフォルト状態の瞬間移動のように通常のサイト内移動になってしまいます。
<!-- 正常に動く -->
<a href="#anchor01">リンク</a>
<!-- 正常に動かない -->
<a href="https://○○.com/#anchor01">リンク</a>
これだとせっかく設定したのに意図した動作にならない。という事になり、それを修正するための解説記事となっています。
改めてこれを書いての結果論ですが、今回のコードの方が相対パス・絶対パスのどちらでも動くため、今回のコードを使った方が多くのケースに対応できるため良いのでは無いかなと個人的には思っています。
実際のJavaScriptのコード
では、実際のコードを見ていきましょう。
基本的なところは、前回解説しているコードとほとんど同じになりますので、前回の記事も復習がてら見ておいてください。
- jQueryでページ内リンクをスムーススクロールにする設定とコード
- 以前に、スムーススクロールをCSSだけで設定する方法について解説しましたが、今回はCSSではなくjQueryを使って、ページ内リンクをクリックした際に...
$(function(){
$('a:not(.nosmooth)[href*="#"]').click(function(){
const adjust= 0;
const speed = 700;
const target = $(this.hash === '#' || '' ? 'html' : this.hash)
if(!target.length) return;
const position = target.offset().top - adjust;
$('body,html').animate({scrollTop:position}, speed, 'swing');
return false;
});
});
変わっているのは3箇所のみになります。
それら以外は全く同じ以前のコードを使っています。
これで、絶対パスで記載したリンクもスムーススクロールとして動いてくれます。
コードの解説
では、それぞれのコードを見ていきましょう。
$('a:not(.nosmooth)[href*="#"]').click(function(){
2行目のここは、:notのところは以前にも解説した、スムーススクロールを除外するための設定で同じです。変わったところは、href*=
になったところです。以前はhref^=
となっています。
^=だけだと、「#から始まるもの」が対象になってしまうため、*=にすることで、「#が含まれるもの」が対象になるため、絶対パスでも#が含まれていれば正常に動作するようになります。
$(this.hash === '#' || '' ? 'html' : this.hash)
ここの部分で、idが#だけ、もしくは空の状態(<a href=””>
のこと)の場合はhtmlを、それら以外ならその値を取得して処理されます。簡単に言えば、ここでIDが設定されているかどうかを判断し、設定されていれば処理するといった形になります。
if (!target.length) return;
ここはエラーが起きた時用の処理になります。次の行でエラーが起きてしまった時に抜け出すためのコードとなります。
それら以外は、前回の解説時と同じです。
スムーススクロールを除外するクラスの設定も、スクロール時のヘッダー固定などのための高さ調整用の設定なども同じになります。
あくまでもサイト内リンクで動作する
このコードで、絶対パスで書かれたリンクでもスムーススクロールに対応できるようになりますが、注意点としては、外部リンクや外部のリンクからのスムースリンクに対応しているわけではありません。
絶対パスというと、つい外部リンクのイメージをしてしまいますが、リンクの書き方を相対パスではなく絶対パスで書いたというだけの違いで、外部のページなどに対応しているわけではありません。
WordPressなどのように、リンク先のURLが絶対パスで書かれる仕様などに対処できるものになります。
絶対パスで書かれたリンク先のURLはスルーされる
このコードは先ほどの解説でもあったように、「#が含むURLかどうか」、そして「指定のIDがあるか」で判断がされています。
そのため、アンカーリンクの場合、リンクURLに書かれたリンク先のURLはどんなURLでも実質スルーされる事になります。どういう事かというと、例えばこのサイトで
<a href="https://www.yahoo.co.jp/#menu01">リンク</a>
このように書いたとしたら、通常だとYahooへ飛びますが、このJavaScriptのコードが書かれていると、サイト内の#menu01に飛びます。すなわち、#以前のリンク先URLは全く見られないという事になります。
ただし、サイト内に#menu01というIDの指定がなかった場合は、指定したURLへ飛ぶという事になります。
言葉で書くと非常にややこしい感じになりますが、実際に下記にそのデモを用意したのでご確認いただけます。
通常の使い方であれば特に問題になることはありませんが、例えば#などのアンカーをつけて、外部リンクを張るとき、そのアンカーが、そのページ内にもあった場合、動作が意図した動作と違うことになってしまう点に注意が必要です。
まとめ
絶対パスを使ったスムースリンクについてまとめてみました。
通常のHTMLとCSSでサイトを作るといったようなケースでは、自分のサイト内のリンクを絶対パスで書くという事は無かったりする事も多いので、使う事ある?と思う方もいるかもしれません。
しなしながら、WordPressでサイトを作る際はリンクはWordPressのコードだと絶対パスで書かれるため、その場合はこれを使わなければならないですし、ヘッダーやフッターなど共通メニュー用として絶対パスでリンクを書くという作り方をする事もあるかと思います。
そういった時、以前のコードではうまくスムーススクロールが動作しないため、今回のコードで対処する必要があります。ただし、注意点もいくつかあるのでそのあたりをしっかり理解した上で使う必要があります。
スムーススクロールについて色々見て来ましたが、外部リンクからでもスムーススクロールを発動したいというケースにおいてもあったりするので、それはまた別で後日に解説していければと思います。
記事のシェアにご協力お願いします