【更新日 : 】
【脱Jquery】javascriptでスムーススクロールを実装する
Category: JavaScript
Tags: JavaScript, requestAnimationFrame, Vanilla JS, アニメーション, スクロール, レイアウト, 脱Jquery, 自作関数
Vanilla JSでスムーススクロールを実装したサンプルです。
イージングのカスタマイズにも対応しています。
See the Pen
Smooth Scroll JavaScript (Easing support) by web_nak (@web_walking_nak)
on CodePen.
HTML
<p><a href="#img">画像まで移動</a></p>
<p id="img"><img src="https://picsum.photos/id/1003/500/600" alt="" width="500" height="600"></p>
アンカーリンクを設定してください。特に特別な実装はありません。
JS
/**
* スムーススクロール関数
*/
const smoothScroll = () => {
//スクロールリンク取得
const targets = document.querySelectorAll('a[href^="#"]');
if(targets.length === 0) {
return;
}
/*
イージング設定
・参考サイト
https://github.com/danro/jquery-easing/blob/master/jquery.easing.js
https://noze.space/archives/432#index-3
「t:アニメーションの経過時間」「b:始点」「c:変化量」「d:変化にかける時間」
*/
const easing = (t, b, c, d) => {
return c * (0.5 - Math.cos((t / d) * Math.PI) / 2) + b;
}
//スクロール速度
const animeSpeed = 600;
const scrollBusyClass = 'is-scroll-busy';
const body = document.body;
const bodyClassList = body.classList;
//クリックイベント設定
targets.forEach(target => {
target.addEventListener('click', event => {
event.preventDefault();
//スクロールイベント重複防止
if (bodyClassList.contains(scrollBusyClass)) {
return;
}
bodyClassList.add(scrollBusyClass);
//hrefから遷移先を取得
const href = target.getAttribute('href');
const scrollStopTarget = document.querySelector(href == '#' || href == '' ? 'html' : href);
//遷移先が存在しない場合は処理しない
if (!scrollStopTarget) {
return;
}
//移動先取得
const scrollStopTop = scrollStopTarget.getBoundingClientRect().top;
//現在のスクロール量
const scrollTop = window.pageYOffset;
//アニメーション開始時間
let start;
//スクロールアニメーション関数
const startAnime = () => {
requestAnimationFrame(mainAnime);
}
const mainAnime = timestamp => {
//イベント発生後の経過時間
// start未定義時のみtimestampを代入することで一度だけstartに数値を格納する
if (start === undefined) {
start = timestamp;
}
// 経過時間を監視
const elapsedTime = timestamp - start;
//アニメーション終了処理
if (elapsedTime > animeSpeed) {
//実行中class削除
bodyClassList.remove(scrollBusyClass);
//処理を終了
return;
}
//スクロール処理
window.scrollTo(
0,
//「アニメーションの経過時間」,「始点」,「変化量」,「変化にかける時間」
easing(elapsedTime, scrollTop, scrollStopTop, animeSpeed)
);
startAnime();
}
//アニメーション初回呼び出し
startAnime();
});
});
}
イージング設定やスクロール速度はサイトに合わせて編集してください。
関数の呼び出し
任意の場所で以下を実行し関数を呼び出してください。
//スムーススクロール関数呼び出し
smoothScroll();
参考リンク
- nativeなJavaScript(Vanilla JS)を使って速度が変動するスムーズスクロールを実装してみた
- jquery.easing.js
- 【JavaScript】スムーススクロールをjQueryを使わずにシンプルに実装する【Vanilla JS】