jQueryを使わないでページ内リンクのスムーズスクロールを実装する

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

参考サイト

このエントリーをはてなブックマークに追加

関連記事

コメントを残す

メールアドレスが公開されることはありません。
* が付いている欄は必須項目です

CAPTCHA


コメントが承認されるまで時間がかかります。

2024年4月
 123456
78910111213
14151617181920
21222324252627
282930