2016/02/23

エラー箇所など指定した要素にスクロールで移動する

photo by mollyali

縦長Webページの入力フォームなどで、バリデーション後にエラーを表示したいことがある。その方法はいくつもあるが、今回はエラー箇所にスクロールで移動する方法を実装する。

※サンプルではjQueryを使用しているが、使わなくても対応可能(アニメーションが面倒だけど)



特定の要素にスクロールで移動する


var position = $('セレクタ').get(0).offsetTop;
$('body').animate({scrollTop: position}, 'slow');

要素の位置を取得するには $('セレクタ').get(0).offsetTop を使う。
$('セレクタ').offset().top で位置を取得するとズレる場合があるので注意。
また、複数ある要素のうち1番目に移動したい場合は、 $(‘セレクタ:first’).get(0).offsetTop とも書ける。


次に、スクロールにアニメーションをつける場合は $(‘セレクタ’).animate({scrollTop: position}, ‘スピード) を使う。
jQueryを使わない場合は、 document.getElementById(‘セレクタ’).scrollTop = position となる。


ちなみにスクロールするときのセレクタには、スクロールバーが表示されている箇所を選択する。
例えば以下のような構造の場合
<div class="container">
    <div id="main">
    </div>
    <div id="side">
    </div>
</div>
ここでmainをスクロールさせたいなら $(‘#main’).animate() と書くし、sideをスクロールさせたいなら $(‘#side’).animate() と書く。

スピードの部分は、以下の中からアニメーションに適した速さを選ぶ。
  • slow
  • normal
  • fast
  • ミリ秒


実践: 入力フォームのエラー箇所にスクロールで移動する


テキストエリアが12個並んでいて、clickボタンを押下するとバリデーションが走る。
もし未入力ならclassに「error」を追加して、その箇所までスクロールする。

<!-- index.html -->
<body>
<ol>
  <li><textarea rows="5"></textarea></li>
  <li><textarea rows="5"></textarea></li>
  <li><textarea rows="5"></textarea></li>
  <li><textarea rows="5"></textarea></li>
  <li><textarea rows="5"></textarea></li>
  <li><textarea rows="5"></textarea></li>
  <li><textarea rows="5"></textarea></li>
  <li><textarea rows="5"></textarea></li>
  <li><textarea rows="5"></textarea></li>
  <li><textarea rows="5"></textarea></li>
  <li><textarea rows="5"></textarea></li>
  <li><textarea rows="5"></textarea></li>
</ol>

<div id="button">
  <a href="#" id="check">click</a>
</div>
</body>
// script.js
$(function(){
  var validator = function () {
    $('textarea').each(function (i) {
    if (!$(this).val()) {
        $(this).addClass('error');
      } else {
        $(this).removeClass('error');
      }
    });
  };

  $('#check').click(function(){
    validator();

    var errorPos = ($('.error:first').offset() && $('.error:first').offset().top) || 0;
    // ずれるときは $().get(0).offsetTop を使う
    $('body').animate(
      {scrollTop: errorPos},
      'slow'
    );
  });
});
/* style.css */
.error {
  color: red;
  background-color: pink;
}

ul {
  list-style-type: none;
}

li > textarea {
  width: 80%;
}

#button {
  position: fixed;
  top: 10px;
  right: 10px;
}

#check {
  text-decoration: none;
  display: block;
  
  height: 30px;
  width: 80px;
  text-align: center;
  color: white;
  background-color: #55acee;
}

#check:hover {
  background-color: #83c3f3;
}




以上

written by @bc_rikko

0 件のコメント :

コメントを投稿