jQueryを使わない案件でスムーズスクロールを実装する機会があったので、実装方法をメモ。
実装方法1
scrollTo()のオプションでbehavior: ‘smooth’を設定することで、スムーズスクロールが実装できるようです。
ページ内リンクを設定するリンク要素に対して.js-pagelinkを付与するようにします。
<ul> <li><a href="#section1" class="js-pagelink">セクション1</a></li> <li><a href="#section2" class="js-pagelink">セクション2</a></li> <li><a href="#section3" class="js-pagelink">セクション3</a></li> </ul> <section id="section1" class="section"> <h2>セクション1</h2> </section> <section id="section2" class="section"> <h2>セクション2</h2> </section> <section id="section3" class="section"> <h2>セクション3</h2> </section>
JavaScriptでスムーズスクロールの処理を実装します。
var pagelink = document.querySelectorAll('.js-pagelink');
for( var i = 0; i < pagelink.length; i++ ) {
pagelink[i].addEventListener('click', smoothScroll, false);
}
function smoothScroll(e) {
e.preventDefault();
// 遷移先の要素
var pagelinkId = e.target.hash;
var pagelinkSection = document.querySelector(pagelinkId);
// スクロール先の位置
var scrollPosition = window.pageYOffset + pagelinkSection.getBoundingClientRect().top;
// スクロールで移動
window.scrollTo({
top: scrollPosition,
behavior: "smooth"
});
}
スムーズスクロールのデモページ
これでchrome,firefox,edgeは問題なかったのですが、safariとIEではうまく動作しませんでした。
実装方法2
先ほどの実装を修正して、safariとIE用に別途処理を追加する形にしてみます。
var pagelink = document.querySelectorAll('.js-pagelink');
/* scrollToのOptionsに対応しているかのどうかの判別 */
var smoothScrollType;
if('scrollBehavior' in document.documentElement.style) {
smoothScrollType = smoothScroll;
} else {
smoothScrollType = oldTypeSmoothScroll;
}
for( var i = 0; i < pagelink.length; i++ ) {
pagelink[i].addEventListener('click', smoothScrollType, false);
}
/* scrollToのOptionsに対応している場合 */
function smoothScroll(e) {
e.preventDefault();
// 遷移先の要素
var pagelinkId = e.target.hash;
var pagelinkSection = document.querySelector(pagelinkId);
// スクロール先の位置
var scrollPosition = window.pageYOffset + pagelinkSection.getBoundingClientRect().top;
// スクロールで移動
window.scrollTo({
top: scrollPosition,
behavior: "smooth"
});
}
/* scrollToのOptionsに対応していない場合 */
function oldTypeSmoothScroll(e) {
e.preventDefault();
// スクロール速度の設定
var scrollSpeed = 300;
var timerStep = 20;
// 遷移先の要素
var pagelinkId = e.target.hash;
var pagelinkSection = document.querySelector(pagelinkId);
// スクロール先の位置
var scrollPosition = window.pageYOffset;
var sectionPosition = pagelinkSection.getBoundingClientRect().top;
var goalPosition = scrollPosition + sectionPosition;
// スクロール量
var scrollStep = sectionPosition / (scrollSpeed / timerStep);
var currentScroll = scrollPosition;
// スクロールの実行
var smoothScrollTimer = setInterval(function() {
// スクロール完了時
if(currentScroll >= goalPosition) {
// スクロール位置を完了位置に設定
window.scrollTo(0, goalPosition);
// タイマーのクリア
clearInterval(smoothScrollTimer);
} else {
currentScroll += scrollStep;
window.scrollTo(0, currentScroll);
}
}, timerStep);
}
これでsafariやIEでもスムーズスクロールされるようになりました。
スムーズスクロールのデモページ2
oldTypeSmoothScroll()という関数を用意して、behavior: ‘smooth’に対応していない場合の処理を追加しています。
元の処理との出しわけは6行目の if(‘scrollBehavior’ in document.documentElement.style) で行っています。
実装方法3
behavior: ‘smooth’に対応するためのpolyfillがあるようなので、実装方法1に読み込みを追加してみます。
polyfillはこちらからインストールしてください。
インストール後、読み込みを追加します。
<script src="smoothscroll.js"></script>
これでsafariやIEでもbehavior: ‘smooth’が効くようになりました。
スムーズスクロールのデモページ3
コメントが承認されるまで時間がかかります。