こんにちは、けいすけです。
今回は、nativeなJavaScript(Vanilla JS)を使って、ページ内リンクをクリックしたときに、速度が変動する(正弦波の動きで動作する)スクロールを実装したので、共有してみたいと思います。
※ここでの正弦波の動きとは、リンク元とリンク先付近が最も遅く、中間地点が最も早い動きのことを指します。
目次 [表示する]
スクロールの実装
完成形
完成形がこちらです。
JavaScript
const scrollBtn = document.getElementsByClassName('scroll-btn');
for(let i = 0; i < scrollBtn.length; i++){
scrollBtn[i].addEventListener('click', function(event) {
event.preventDefault();
let myHref = this.getAttribute('href');
let scrollStop = document.querySelector(myHref);
let scrollStopTop = scrollStop.getBoundingClientRect().top;
let scrollTop = window.pageYOffset || document.documentElement.scrollTop;
let start = new Date();
let time = 400;
let intervalID = setInterval(function() {
let elapsed = new Date() - start;
if (elapsed > time) {
clearInterval(intervalID);
elapsed = time;
}
window.scrollTo(0, scrollStopTop * ((-1) * Math.cos((elapsed / time) * Math.PI) + 1) / 2 + scrollTop);
}, 10);
});
}
上記を実装したものがこちらです。すぐ下の見出しまで移動します。
スクロール実装の考え方
それでは、順に説明していきます。
まず最初に以下のようにして、クリックしたときに処理が行われるような記述をしていきます。
ちなみに、“getElementsByClassName()”で取得した値は、配列となるため、for文を使用しています。
今回は、スクロールによるページ遷移を行うため、リンクによるページ遷移は、”preventDefault()”を使って無効にします。
const scrollBtn = document.getElementsByClassName('scroll-btn');
for(let i = 0; i < scrollBtn.length; i++){
scrollBtn[i].addEventListener('click', function(event) {
event.preventDefault();
// ここにリンクをクリックしたときの処理を記述する
});
}
具体的な処理内容を記述する前に、リンク先となる要素のトップの位置と、現在のスクロールの位置を以下のようにして取得します。
let myHref = this.getAttribute('href');
let scrollStop = document.querySelector(myHref);
let scrollStopTop = scrollStop.getBoundingClientRect().top;
let scrollTop = window.pageYOffset || document.documentElement.scrollTop;
nativeなJavaScriptでアニメーションを実装するときは、以下のように“setInterval()”を使用して繰り返し処理を実装します。
以下の場合だと、10ミリ秒毎に400ミリ秒かけて、指定の処理が繰り返し行われます。
let start = new Date();
let time = 400;
let intervalID = setInterval(function() {
let elapsed = new Date() - start;
if (elapsed > time) {
clearInterval(intervalID);
elapsed = time;
}
// ここにアニメーションさせたい処理を記述する
}, 10);
実装したい処理はスクロールのため、”scrollTo(x, y)”を使用します。
スクロールは、正弦波のような動きで動作させたいので、y方向のスクロール位置を経過時間に対する三角関数で記述しています。
この関数を編集することで、様々な動きのアニメーションを実装することが可能です。
window.scrollTo(0, scrollStopTop * ((-1) * Math.cos((elapsed / time) * Math.PI) + 1) / 2 + scrollTop);
ここで、それぞれの変数は以下です。
- scrollStopTopは、リンク先となる要素のトップの位置
- elapsedは、イベント発生後の経過時間
- timeは、アニメーション時間
- scrollTopは、現在のスクロールの位置
今回は、nativeなJavaScript(Vanilla JS)を使って実装しましたが、スクロールのようなアニメーションは、jQueryを使うともっと簡単に実装することが可能です。
しかし、jQueryは、簡単に実装できる分使用量が多いと、nativeなJavaScriptに比べてファイルサイズが大きくなったり、Webページの表示速度が遅くなったりします。