スムーススクロールがうまく動かない場合の解決方法
比較的簡単に実装できることもあって、
昨今リッチなWEBサイトにはまず必ずといっていいほど使われているスムーススクロールですが、
場合によってよく使われる書き方のままではうまく動いてくれない場合があります。
例えばワードプレスなどを使用している時にナビゲーションを共通で読み込んでいる場合で、
ナビゲーション部分に絶対パスの後にハッシュ(#)を記述している場合などです。
例) http://hogehoge.com#foo
解決方法
解決方法は2つ
- phpなどで条件分岐を使い、対象ページの場合はハッシュ以前を出力しないようにする
- スムーススクロールのコードを修正する
「1」の場合の解決方法が多くの場合は適当かと思いますが、
リンク先が多い場合などは修正箇所が多くなるので、避けたいこともあるかと思います。
そこで以下では「2」の場合の解決方法をご紹介したいと思います。
スムーススクロールのコードの修正方法について
下記はTECH ACADEMYさんで紹介されているスムーススクロールのコードです。
参照元
$(function(){
$('a[href^="#"]').click(function(){
var speed = 500;
var href= $(this).attr("href");
var target = $(href == "#" || href == "" ? 'html' : href);
var position = target.offset().top;
$("html, body").animate({scrollTop:position}, speed, "swing");
return false;
});
});
フルパスを含むページ内リンクの場合は何処が問題になるかというと、
$('a[href^="#"]').click(function(){
前半の方のここの部分で、ページ内リンクの対象となる
ハッシュを先頭に持つurlのリンクをクリックしたときに処理を行なうよ、
という感じの動きをするのですが、
今回のケースではリンク先のurlの先頭にハッシュが来ていないので、
上記の処理では対象にならないというのが原因です。
そのため、現在表示中のページをリンク先に持つアンカータグを
処理の対象に含めてあげるための記述をしてあげる必要があります。
修正したJSコード
修正のポイントは大まかに2点です。
- 全てのアンカータグを対象にすること
- 現在表示中のurlを取得して、リンクを整形すること
上記を踏まえて、修正したコードが下記になります。
$(function(){
// 全てのアンカータグを対象にする
$('a').click(function(e){
var anchor = $(this),
href = anchor.attr('href'),
pagename = window.location.href;
// 現在のurlのハッシュ以降を削除
pagename = pagename.replace(/#.*/,'');
// リンク先のurlから現在の表示中のurlを削除
href = href.replace( pagename , '' );
if( href.search(/^#/) >= 0 ){
// 整形したリンクがページ内リンクの場合はページ無いスクロールの対象とする
// 通常の遷移処理をキャンセル
e.preventDefault();
var speed = 500;
// 前段階で整形したhrefを使用する
// var href= $(this).attr("href");
var target = $(href == "#" || href == "" ? 'html' : href);
var position = target.offset().top;
$("html, body").animate({scrollTop:position}, speed, "swing");
// ロケーションバーの内容を書き換え
location.hash = href ;
return false;
}
});
});
また、上記のコードではおまけに
ロケーションバーをハッシュ付きに書き換える処理も行っています。
なお、このコードはリンクが絶対パスになっている場合には有効ですが、
相対リンクなどの場合には機能しないのでご注意くださいね!