6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

クリックで指定要素が画面中央に来るようにスクロールする

Last updated at Posted at 2021-01-06

#概要
クリックで指定の要素が画面中央に来るようにスクロールする動きを実装したときのメモです。

今回はアンケートなどの「ラジオボタンでたくさん選択するようなフォーム」で、回答すると次の質問が画面中央にスクロールされていく、というものを作りました。

▼こんなかんじ
2c6f4e446e97d3d19f14aa5aef8c66a0.gif

#実装
HTMLは以下のようになっています。

<li class="qs_col">~</li>が1つの質問のブロックになっているので、
「質問1のラジオボタンを選択すると、スクロールして質問2が画面中央に表示される」
ようにしてみます。

index.html
<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でのイベント検知にしています。

scroll.js

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です。

index.html
<script src="./scripts/smoothscroll.min.js"></script>
<script src="./scripts/scroll.js"></script>

 
これで実装は以上です!

#参考
【メソッドについて】

 
【ポリフィルについて】

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?