webサイトにはかならずと言っていいほど実装されるスムーススクロール。
わたしもJavaScriptを勉強した当初真っ先に調べたコードでした。
そんなスムーススクロールを今回はjQuery版とJavaScript版のコード、どちらも書いていこうと思います。
どちらも前提にHTMLファイルにてリンク先はid付与しています
#jQueryでスムーススクロール
$(function () {
// 対象となるセレクターを取得し、クリックイベントに無記名関数を代入
$('a[href^="#"]').click(function () {
// href属性の属性値を取得
let href = $(this).attr('href');
// 取得した属性値から飛び先のセレクターを取得(三項演算子をつかってます)
let target = $(href == '#' || href == '' ? 'html' : href);
// 飛び先の位置を取得
let pos = target.offset().top;
// bodyとhtmlにanimationプロパティを付ける
$('body,html').animate({
scrollTop: pos
}, 400, 'swing');
return false;
});
});
- $('a[href^="#"]')で"#"からはじまるaタグをすべて取得します。
- クリックされた、$('a[href^="#"]')のhref属性の値を取得します。
- 三項演算子(条件式 ? true : false)をつかって飛び先のセレクターを取得し、変数targetに代入します。
- offset()メソッドを使用し、targetのtopからの位置を取得し変数posに代入します。
- bodyとhtmlにanimationプロパティを付けて完成!
#JavaScriptでスムーススクロール
const a = document.querySelectorAll('a[href^="#"]');
for (let i = 0; i < a.length; i++) {
a[i].addEventListener("click", (e) => {
e.preventDefault();
let href = a[i].getAttribute("href");
let target = document.getElementById(href.replace("#", ""));
// 要素の上端のY座標を取得
const rect = target.getBoundingClientRect();
// 現在のスクロール値を取得
const set = window.pageYOffset || document.documentElement.scrollTop;
const pos = rect.top + set;
window.scrollTo({
top: pos,
behavior: "smooth",
});
});
}
手順としては同じです。
違うとすれば、
const rect = target.getBoundingClientRect(); const set = window.pageYOffset || document.documentElement.scrollTop; const pos = rect.top + set;
の部分ですね。
getBoundingClientRect()はwindow上の座標の位置を返します。
rect.topで要素の上端のY座標を取得しています。
const set = window.pageYOffset || document.documentElement.scrollTop;
ではwindow.pageYOffsetがtrue(値あり)の場合、変数setに代入されますが
window.pageYOffsetに対応していないブラウザ用に後者のルート要素(html要素)のscrollTopを用意しています。
最終的な移動量はrect.topに現在のスクロール量を足したものとなります。
そうでないと、現在スクロールしている分だけ移動量が足りずスクロールが止まってしまいます。
あとはヘッダーの長さなどいろいろと各仕様に合わせて移動量を調整してもいいですね。
#まとめ
個人的にはなるべくJavaScriptで書きたいですが、コードが短くなるjQueryはやっぱり魅力的ですね。
また、座標関係のメソッドやプロパティは基準値が色々あるので理解を深めていきたいです。