shopifyでsmoothscrollがちゃんと動作しない問題

フロントエンドエンジニア・デザイン・イラストレーター MISAKO MIMURA
  • このエントリーをはてなブックマークに追加

問題

最近では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コードで色々対応したコードを使いまわしたい!精神です。
良かったら活用してみてください♪

  • このエントリーをはてなブックマークに追加

書いた人

フロントエンドエンジニア・デザイン・イラストレーター MISAKO MIMURA

フロントエンドエンジニアとして主にWPとshopifyの開発に携わっています。 開発での進行管理・開発チームのOJTなども担当。 猫とアニメが大好きです。飼い猫にはあまり好かれていません。