こんにちは!フリーランスWebディレクター兼エンジニアののせっち@nosecchi01です。
Javascriptのみでスムーススクロールを実装してみましょう。
僕はこれまでjQueryで実装してきましたが、Javascriptでも簡単に実装できます。
それではいってみましょう!
目標物を確認
早速コードペンで見てみましょう!
See the Pen Smooth Scroll (Javascript) by Yuki Nose (@yukinouz1) on CodePen.
下記のような仕様です。
- ページ内リンクa href=”#id” クリックで該当のidにジャンプする
- スムースにジャンプする(ぬるっとスクロール)
- 固定ヘッダー分の高さも考慮
それでは行ってみましょう!
Javascriptの全体像を確認
まず大まかな流れを確認し、その後細かく分解して見ていきましょう!
const smoothScrollTrigger = document.querySelectorAll('a[href^="#"]');
for (let i = 0; i < smoothScrollTrigger.length; i++){
smoothScrollTrigger[i].addEventListener('click', (e) => {
e.preventDefault();
let href = smoothScrollTrigger[i].getAttribute('href');
let targetElement = document.getElementById(href.replace('#', ''));
const rect = targetElement.getBoundingClientRect().top;
const offset = window.pageYOffset;
const gap = 60;
const target = rect + offset - gap;
window.scrollTo({
top: target,
behavior: 'smooth',
});
});
}
大まかな流れ
- href=”#”のaタグを取得(→その後、href属性からid名を抜き出す)
- for文を回して、aタグそれぞれに対してクリックイベント
- ターゲットの位置を取得
- スムースにスクロールする
href=”#”のaタグを取得(→その後、href属性からid名を抜き出す)
const smoothScrollTrigger = document.querySelectorAll('a[href^="#"]');
これでa href="#{id名}"
となっているものを取得しています。
このaタグがクリックされたときに、同じid名の場所に移動したいので、ここからid名を抜き出してあげる必要があります。
それが下記の部分です。
const smoothScrollTrigger = document.querySelectorAll('a[href^="#"]');
for (let i = 0; i < smoothScrollTrigger.length; i++){
smoothScrollTrigger[i].addEventListener('click', (e) => {
e.preventDefault();
let href = smoothScrollTrigger[i].getAttribute('href');
let targetElement = document.getElementById(href.replace('#', ''));
// 省略
e.preventDefault();
でデフォルトの動作をキャンセルします。これを書かないと、スムーススクロールなしでジャンプしてしまいます。
let href = smoothScrollTrigger[i].getAttribute('href');
でhref=””の中身を取得します。
下記のような感じで、試しにconsole.logしてあげるとわかります。
const smoothScrollTrigger = document.querySelectorAll('a[href^="#"]');
for (let i = 0; i < smoothScrollTrigger.length; i++){
smoothScrollTrigger[i].addEventListener('click', (e) => {
e.preventDefault();
let href = smoothScrollTrigger[i].getAttribute('href');
console.log(href) // 結果:#menu1
// 省略
let targetElement = document.getElementById(href.replace('#', ''));
で#を除きます。
ここでもconsole.logしてみます。
const smoothScrollTrigger = document.querySelectorAll('a[href^="#"]');
for (let i = 0; i < smoothScrollTrigger.length; i++){
smoothScrollTrigger[i].addEventListener('click', (e) => {
e.preventDefault();
let href = smoothScrollTrigger[i].getAttribute('href');
let targetElement = document.getElementById(href.replace('#', ''));
console.log(targetElement) // 結果:menu1
// 省略
これでジャンプする先のid名を抜き出すことができました。(targetElement
に代入した)
for文を回して、aタグそれぞれに対してクリックイベント
for (let i = 0; i < smoothScrollTrigger.length; i++){
smoothScrollTrigger[i].addEventListener('click', (e) => {
});
a href="#"
全てをsmoothScrollTrigger
に代入しましたので、for分を回して一つ一つに対してクリックイベントを起こしてあげます。
ターゲットの位置を取得
先ほど、ターゲット(ジャンプする先)のid名を取得し、targetElement
に代入しましたね。
それを元にtargetElement
の位置を計算します。
具体的には下記の部分です。
const rect = targetElement.getBoundingClientRect().top; // ブラウザからの高さを取得
const offset = window.pageYOffset; // 現在のスクロール量を取得
const gap = 60; // 固定ヘッダー分の高さ
const target = rect + offset - gap;
jQueryの場合は、offset().top
でウィンドウからターゲットまでの位置を取得できるのですが、javascriptにはありませんので、計算で求めます。
この辺りは下記の記事で詳しく解説しました。
const gap = 60; // 固定ヘッダー分の高さ
const target = rect + offset - gap;
僕のcodepenの例では、固定ヘッダーの場合を想定しています。
固定ヘッダー分を計算してあげないと、ジャンプ後にヘッダーが被ってしまいますのでgap = 数値;
としています。
固定ヘッダーでない場合は、gap = 0とするか、消してしまえばOKです。
const target = rect + offset;
で、ウィンドウからターゲットまでの距離を取得できます。
スムースにスクロールする
window.scrollTo({
top: target,
behavior: 'smooth',
});
特に解説することはないですね。
こちらは、別記事の「ページトップへ戻るボタン」でも使用しました!
解説は以上です。
下記の記事を参考にさせていただきました!本当にありがとうございますm(_ _)m
今どきのスムーズスクロール(2019年版)
https://www.to-r.net/media/smooth_scrolling_2019/
意外と簡単!jQueryを使わずにJavaScriptだけでスムーススクロールを実装する(IE11以上版)
https://launchcart.jp/blog/%E6%84%8F%E5%A4%96%E3%81%A8%E7%B0%A1%E5%8D%98%EF%BC%81jquery%E3%82%92%E4%BD%BF%E3%82%8F%E3%81%9A%E3%81%ABjavascript%E3%81%A0%E3%81%91%E3%81%A7%E3%82%B9%E3%83%A0%E3%83%BC%E3%82%B9%E3%82%B9%E3%82%AF/
Javascriptのおすすめ勉強法
学習サイトとしてはドットインストールがオススメです。
僕は基本Progate派なのですが、Javascriptに関してはドットインスールが最適です。
- とにかく講座数が多い(課金は必須)
- 実際にアプリを作りながら学べるので実践に近い
- よく使う技術は何度も出てくるため、自然と覚えられる
Javascriptのオススメ書籍
Javascriptでオススメの書籍はこちらです。
正直内容はツマラナイのですが・・・。
タイトル通り「コードレシピ集」となっており、辞書的に使うのに最適です!
上記のドットインストールと合わせて使うことで、内容を補完し合えるのでオススメです。
まとめ
・Javascriptのみでスムーススクロールを実装する方法を見ていきました。
・Javascriptの場合、一つ一つ値を取得していくので処理の流れがわかりやすいですね!