問題
最近ではCSSで簡単にぬるっとしたスムーススクロールが実装できます。
html {
scroll-behavior: smooth;
}
しかし、ヘッダーをfixedにしてるとページ内リンクで要素がヘッダーに隠れてしまう!
paddingとmarginで相殺して調整する方法もあるけど、見る環境によってはズレます。
そのためJQなんかでスムーススクロールを実装する現場は多いと思います。
しかし!shopifyでは普通に動いてたはずのコードが動かないというのは結構あるある問題。
一般的によく紹介されてるコードが動かなかったので書き直しました。
よく紹介されてるコードパターン
/* スムーススクロール
---------------------------------------------------*/
function smooth_scroll() {
$('a[href^="#"]').click(function () {
var windowWidth = $(window).width();
var headerHight; //ヘッダの高さ
if (windowWidth > 750) {
headerHight = 70;
} else {
headerHight = 0;
}
var speed = 500;
var href = $(this).attr("href");
var target = $(href == "#" || href == "" ? 'html' : href);
var position = target.offset().top - headerHight;
$("html, body").animate({
scrollTop: position
}, speed, "swing");
return false;
});
}
原因
検証を進めるとvar href = $(this).attr(“href”) → $(href) がshopifyでは空になる(hrefのリンク先がDOM上で見つけられない)。
トリガー:$(‘a[href^=”#”]’) (先頭一致)だと動かない。 $(‘a[href*=”#”]’) 部分一致に変更で動く。
解決コード
/* スムーススクロール
---------------------------------------------------*/
function smooth_scroll() {
$('a[href*="#"]').click(function () {//先頭一致では動かないので部分一致にする
var headerHight=250; //ヘッダーの高さ指定
var speed = 500;//スピード指定
var href = $(this).attr('href').split("#").slice(-1);//クリックした要素のhrefを取得
var target = $(href == "#" || href == "" ? 'html' : '#'+href);//移動先を指定
var position = target.offset().top - headerHight;//ポジションからヘッダーの高さ分引く
var w = $(window).width();//レスポンシブ分岐用 ウインドウ幅取得
if (w <= 734) {// 749だとずれる //スマホ版のヘッダー高さ指定
headerHight = 0;//SP版は固定ヘッダーなし
}
$("html, body").animate({
scrollTop: position//スムーススクロール実行
}, speed, "swing");
return false;
});
}
これでレスポンシブ対応+shopify・WP環境は動きます。
解説
軽く解説していきます!
$(‘a[href^=”#”]’) → $(‘a[href*=”#”]’) 変更
var href = $(this).attr(‘href’).split(“#”).slice(-1);
href には、<a href=”../pages/#hoge”>の「hoge」が入るように
var target = $(href == “#” || href == “” ? ‘html’ : ‘#’+href);
href=”#” などの時の場合の記述とそれ以外の指定がある場合 $(’html #hoge’)になる。
var position = target.offset().top – headerHight;
ターゲットのある高さを取得して、指定したヘッダーの高さを引く
$(“html, body”).animate({
scrollTop: position//スムーススクロール実行
}, speed, “swing”);
計算した位置に移動!
基本的に特定の環境でしか動かないより
1コードで色々対応したコードを使いまわしたい!精神です。
良かったら活用してみてください♪