ページ内リンクとページトップへのスムーススクロールの実装 scrollToのOptions未対応にも対応させる

ページ内リンクのスムーススクロール
// リンクをすべて取得
const link = document.querySelectorAll('a[href^="#"]');
// クリックイベント
for (let i = 0; i < link.length; i++) {
link[i].addEventListener("click", smoothScroll, false);
}
function smoothScroll(e) {
// 一瞬でリンク先に飛ぶ初期設定を解除
e.preventDefault();
// 遷移先の要素
let targetId = e.target.hash; // クリックした要素の「#」を取得
let target = document.querySelector(targetId); // 遷移先要素の取得
// 遷移先の位置
let scrollPosition =
window.pageYOffset + target.getBoundingClientRect().top;
// スクロールで移動
window.scrollTo({
top: scrollPosition, // 要素の位置
behavior: "smooth", // オプション選択
});
}
参考

「^=」の意味とは?
ページ内リンクのスムーススクロールやCSSの指定などに使えます‼
ページトップへのスムーススクロール
// トップへ戻るボタンの取得
const btn = document.getElementById("topButton")
// クリックイベント
btn.addEventListener("click", smoothScrolltoTop, false);
function smoothScrolltoTop(e) {
e.preventDefault();
window.scrollTo({
top: 0, // 画面トップ
behavior: "smooth", // オプション選択
});
}
scrollToのOptions未対応のブラウザに対応させる
上のコードではsafari等で動いてくれません。
scrollToのOptionsに対応しているかで分岐
/* scrollToのOptionsに対応しているかのどうかの判別 */
let smoothScrollType;
let smoothScrolltoTopType;
if ("scrollBehavior" in document.documentElement.style) { // scrollToのOptionsに対応している場合
smoothScrollType = smoothScroll; // 上に書いたコード
smoothScrolltoTopType = smoothScrolltoTop; // 上に書いたコード
} else { // scrollToのOptionsに対応していない場合
smoothScrollType = oldTypeSmoothScroll; // これから紹介するコード
smoothScrolltoTopType = oldTypeSmoothScrolltoTop; // これから紹介するコード
}
クリックイベント
// ページ内リンク
var link = document.querySelectorAll('.whiteBoard a[href^="#"]');
for (var i = 0; i < link.length; i++) {
link[i].addEventListener("click", smoothScrollType, false);
}
// ページトップへ
const button = document.getElementById("topbutton");
button.addEventListener("click", smoothScrolltoTopType, false);
oldTypeSmoothScroll
function oldTypeSmoothScroll(e) {
e.preventDefault();
// スクロール速度の設定
let scrollSpeed = 100;
// スクロール先の要素
let pagelinkId = e.target.hash;
let target = document.querySelector(pagelinkId);
// スクロール先要素の位置
let targetPosition =
window.pageYOffset + target.getBoundingClientRect().top;
let currentScroll = window.pageYOffset
// スクロールの実行
let smoothScrollTimer = setInterval(function () {
// スクロール完了時
if (currentScroll >= targetPosition) {
// スクロール先要素の位置を完了位置に設定
window.scrollTo(0, targetPosition);
// setIntervalのクリア
clearInterval(smoothScrollTimer);
} else {
currentScroll += scrollSpeed; // 毎回scrollSpeed(100px)加算
window.scrollTo(0, currentScroll);
}
}, 20); // 20マイクロ秒ごとに処理
}
oldTypeSmoothScrolltoTop
function oldTypeSmoothScrolltoTop(e) {
e.preventDefault();
// スクロール量
let currentScroll = window.pageYOffset;
// スクロールの実行
let smoothScrollTimer = setInterval(function () {
currentScroll -= 100; // 毎回100px減算
window.scrollTo(0, currentScroll);
if (currentScroll < 80) {
window.scrollTo(0, 0);
clearInterval(smoothScrollTimer);
}
}, 20); // 20マイクロ秒ごとに処理
}
参考

【javascript】setIntervalと、それを停止させるclearIntervalの使い方

要素の高さを取得する方法。getBoundingClientRectとは?window.innerHeightとは?window.pageYOffsetとは?

【javascript】よく使う演算子の使い方 "++", "--", "+=", "-=", "%",
"&&", "||"
まとめ
- scrollToのOptionsで「smooth」を指定する。
- scrollToのOptions未対応の場合、スクロール先の位置を計算し、setIntervalその位置まで少しずつスクロールさせる。