#概要
クリックで指定の要素が画面中央に来るようにスクロールする動きを実装したときのメモです。
今回はアンケートなどの「ラジオボタンでたくさん選択するようなフォーム」で、回答すると次の質問が画面中央にスクロールされていく、というものを作りました。
#実装
HTMLは以下のようになっています。
<li class="qs_col">~</li>
が1つの質問のブロックになっているので、
「質問1のラジオボタンを選択すると、スクロールして質問2が画面中央に表示される」
ようにしてみます。
<form method="POST" action="">
<li class="qs_col">
<h2>質問1.~~~~~~~~~~ですか?</h2>
<input type="radio" id="qs01_01" name="qs01" value="0">
<label for="qs01_01">はい</label>
<input type="radio" id="qs01_02" name="qs01" value="1">
<label for="qs01_02">いいえ</label>
</li>
<li class="qs_col">
<h2>質問2.~~~~~~~~~~ですか?</h2>
<input type="radio" id="qs02_01" name="qs02" value="0">
<label for="qs02_01">はい</label>
<input type="radio" id="qs02_02" name="qs02" value="1">
<label for="qs02_02">いいえ</label>
</li>
<li class="qs_col">
<h2>質問3.~~~~~~~~~~ですか?</h2>
<input type="radio" id="qs03_01" name="qs03" value="0">
<label for="qs03_01">はい</label>
<input type="radio" id="qs03_02" name="qs03" value="1">
<label for="qs03_02">いいえ</label>
</li>
<div class="f_btn">
<button type="submit">送信</button>
</div>
</form>
<script src="./scripts/scroll.js"></script>
スクロールを実装します。
フォームはラジオボタンのみなので、クリックを検知してINPUTタグであれば処理を実行します。
functionを作ってinput側にonclick
を記述するのも考えましたが、実際にはラジオが50個以上あり、全てに入れるのが嫌だったのでaddEventListener
でのイベント検知にしています。
window.addEventListener('click', (event) => {
// クリックした要素のタグを取得
var tag = event.target.tagName;
if (tag == 'INPUT') {
// クリックした質問の次のli要素を取得
var id = event.target.id;
var element = document.getElementById(id).closest('li.qs_col').nextElementSibling;
// 最後の質問は次のliが無いので送信ボタンエリアを取得
if (element == null) {
element = document.querySelector('.f_btn');
}
// 要素が画面中央に来るようにスクロール
element.scrollIntoView({behavior: 'smooth', block: 'center'});
}
});
これで、ラジオボタンで回答をクリックすると次の質問ブロックにスクロールします。
#解説
今回はスクロールにElement.scrollIntoView()というメソッドを使いました。
scrollIntoView()が呼び出された要素がユーザーに見えるところまで、要素の親コンテナーをスクロールする、というものです。
最初は次のスクロール位置をoffset().top
などで取得してscrollTop()
を使おうとしたのですが、「要素が画面中央に来るようにスクロール」するためには位置計算などが必要になります。
Element.scrollIntoView()ではそのような計算を使わず、簡単に位置指定することができます。
##Element.scrollIntoView()
Element.scrollIntoView()には3つのオプションがあります。
- behavior:アニメーションの設定
- block:(通常は)垂直方向のスクロール位置設定
- inline:(通常は)水平方向のスクロール位置設定
詳細な設定についてはこちらで詳しく解説されています。
// オプションの設定
element.scrollIntoView({behavior: "smooth", block: "end", inline: "nearest"});
// 今回の場合(アニメーションあり、中央配置)
element.scrollIntoView({behavior: 'smooth', block: 'center'});
今回は画面中央でしたが、上端・下端に合わせることも可能です。
##各ブラウザ対応
scrollIntoView
のオプションはSafariやIEなど一部のブラウザでは対応していません。
そのため、behavior: 'smooth'
を指定してもスムーズスクロールが適用されません。
上記を有効にするためにポリフィルを使う必要があります。
###ポリフィルの利用
ポリフィルとは「対応していないブラウザーで、その機能を使えるようにするためのコード」です。
Javascriptなどを古いブラウザや非対応ブラウザなどでも動くようにしてくれるものになります。
npmなどを使う方法も記述されていますが、ソースダウンロードでも実装できます。
こちらからポリフィルをダウンロードして、スクロールのjsより先に読み込めばOKです。
<script src="./scripts/smoothscroll.min.js"></script>
<script src="./scripts/scroll.js"></script>
これで実装は以上です!
#参考
【メソッドについて】
【ポリフィルについて】