JavaScriptで実装するスムーススクロールの実装方法を完璧に解説
1181 回閲覧されました
みなさんこんにちは、jonioです。
サイト制作でヘッダーメニューをクリックした時にページ内の特定の位置にスーッと動くアニメーションがありますがスムーススクロールと言います。
WEB制作をする時はほぼ必須ですが私がWEB制作を始めた時はjQueryのコピペでしか実装できませんでした。
サイトは作ることができないと意味がないのでそれでもいいのですが言語の理解をしないとスキルが上がらないし応用が効きません。
今回はJavaScriptで実装するスムーススクロールについて解説します。
JavaScriptのコードを全て解説するので頑張って理解してください。
それでは説明します。
ヘッダーメニューですが固定している場合と固定しない場合で実装方法が若干変わります。
まずはヘッダーを固定しない場合です。
ヘッダーを固定しない場合のデモ
デモはここから見ることができます。
ヘッダーを固定しない場合の考え方とコード
まずはHTMLとCSSです。
HTMLとCSS
画面左上の飛び元のメニュー1・メニュー2・メニュー3にaタグをつけます。(↓の赤枠です)
aタグですが↓の様にhref属性の値に必ず「#」を付けて「#〜」にします
今はhref属性が「#menu1」「#menu2」「#menu3」になっています。
そして飛び先にid属性を付けますが飛び元の#以降の名前をid属性の値にします。
「#menu1」の飛び先がid=”menu1“で「#menu2」の飛び先がid=”menu2“で「#menu3」の飛び先がid=”menu3“という具合です。
ここまでのHTMLは↓になります。
CSSは解説しませんがスムーススクロールはWEBサイトを作る時に実装しますが必ずreset.cssが入ります。
だから私が使うreset.cssも入っていますが自分が普段使うreset.cssでいいので必ず入れくてださい。
次はJavaScriptです。
JavaScript
aタグの属性に「#」がある物を全て取得するために「document.querySelectorAll(‘a[href^=”#”]’);」を使いそれを「smoothScrollTrigger」と置きます。
そして「smoothScrollTrigger」のどれかをクリックした時にスムーススクロールを発動するために「for文」の中にクリックした時にやる事を書きます。
以降はfor文の中身です。
「メニュー1」・「メニュー2」・「メニュー3」のどれかをクリックした時を考えるのでコードを↓にします。
今のままだと飛ばし元のaタグをクリックした時にaタグが反応してリンクに入ろうとしてスムーススクロールが動作しません。
飛ばし元は↓です。
飛ばし元をクリックした時に本来作動する内容を消すために「e.preventDefault」を使いコードを↓にします。
そして飛ばし元のaタグのhref属性を取得して「#」を消して飛び先にするためにコードを↓にします。
11行目が飛ばし元のaタグのhref属性を取得していて12行目が飛び先にしています。
次は飛び元から飛び先までの移動量を取得してスムーススクロールで飛び元から飛び先まで移動する様にします。
コードを↓にします。
14行目の「.getBoundingClientRect().top」で画面左上から要素までの距離を取得しています。
14行目の「rect」は17行目の「rect」です。
16行目の「window.scrollTo」で飛び元から飛び先に指定した量だけ移動でき第一引数(この場合rect)が移動量で第二引数がどんな動き(今はsmooth)をするかです。
window.scrollToはこの記事に解説がくわしくあります。
これでヘッダーを固定していない時のスムーススクロールは完成です。
次はヘッダーを固定する場合です。
ヘッダーを固定する場合
サイトを作成する時にヘッダーを固定しない時もあります。
この場合のスムースクロールの移動量は画面一番上から対象の要素までの距離でいいです。
しかしヘッダーを固定する場合ヘッダーも動くのでヘッダーを動いた分の量をスクロールに含めないといけません。
少しシクロールしたのを図にすると↓です。(メニュー2をクリックしてContent2に移動するとします)
赤と青と緑の線を見て欲しいのですが飛び元から飛び先までの移動量(targetElement.getBoundingClientRect().top)が青線でスムーススクロールで移動する量(window.scrollToの中のtop)が赤線です。
ヘッダーを固定しない場合青線がスムーススクロールで移動する量ですが緑線の分足りないです。
そこでJavaScriptのコードを少し追加して↓にします。
ヘッダーを固定するのでCSSが少し変更になるので追加します。
ヘッダーを固定する場合のデモ
デモはここから見る事ができます。
これで完成です。