【初心者でもわかる】select要素を使わずに、セレクトボックスをCSSとjsで再現する方法

【初心者でもわかる】select要素を使わずに、セレクトボックスをCSSとjsで再現する方法

どうも7noteです。select要素にcssが使いにくいので、他の方法を考えてみました。

select要素にはCSSが調整難しいため、自由に調整できるdiv要素でできる方法を書いていきます。
また、PCとスマホでselect要素風とそうじゃない動きに切り分けるなどが必要な時にも使えると思います。

sample.gif

書き方

※jQueryを使用しています。

index.html
<ul>
  <li class="check" link="no1" style="display: list-item;">その1</li> // linkの値と、pタグのクラスを揃える
  <li link="no2">その2</li>
  <li link="no3">その3</li>
  <li link="no4">その4</li>
  <li link="no5">その5</li>
</ul>

<p class="no1">テキスト1</p>
<p class="no2">テキスト2</p>
<p class="no3">テキスト3</p>
<p class="no4">テキスト4</p>
<p class="no5">テキスト5</p>
style.css
ul {
  width: 200px;                   /* セレクトボックスの横幅 */
  border: solid 1px #333;         /* 見やすく境界線を引く */
  position: absolute;             /* 選択肢が開いた時に高さが変わるので指定 */
  top: 0px;                       /* 好きな位置に */
  left: 0px;                      /* 好きな位置に */
}
ul li {
  padding: 5px 10px 5px 20px;     /* optionの余白と同等 */
  display: none;                  /* 最初は非表示 */
  list-style: none;               /* 「・」を非表示にする */
}
ul li.check {
  color: #fff;                    /* 選択されたもののみ装飾 */
  font-weight: bold;              /* 選択されたもののみ装飾 */
  background: #999;               /* 選択されたもののみ装飾 */
}

p {
  display: none;                  /* 最初は非表示 */
  margin-left: 220px;             /* セレクトボックスとかぶらないように位置調整 */
}
script.js
$(function () {
  var click_flg = true;                   // クリックを許可する変数を設定
  $('.check').show();                     // ページ読み込み時、任意のselect1つだけ表示
  $('.no1').show();                       // ページ読み込み時、任意のテキスト1つだけ表示
  $('ul li').on('click', function(){      // セレクトボックスのどれかがクリックされた時
    if(click_flg){                        // クリックが許可されているかどうか
      click_flg = false;                  // ボタンを一時的に無効
      $('ul li').removeClass('check');    // 全てのliからcheckを削除してから、
      $(this).addClass('check');          // 選択されたものにcheckのクラスを付ける
      $('ul li').not('.check').fadeToggle(400, function() { // check以外の表示と非表示を切り替える
        click_flg = true;                   // コールバック関数を使い、アニメーションが終わってからtrueにするように指定
      });
      $('p').hide();                        // pを全て非表示
      $('.' + $(this).attr('link')).show(); // selectされているlinkと同じクラスをもつpだけ表示
    }
  });
});

解説

各行で行なっている動きはコメントでご確認ください。
大まかな処理の流れとしては、、、

  1. ページ読み込み時、任意のselectとテキストを表示。
  2. li要素がクリックされた時、他のliを表示状態に切り換え(fadeToggle)
  3. liが全て開いている状態の時、liがクリックされたら、クリックされたものにのみcheckのクラスを付与、かつ他のliを非表示状態に切り換え。
  4. また同時に、pを全て非表示にしてクリックされたliのlinkと同じクラスを持つpだけ表示。
  5. 結果、選択したli要素と、紐づいているp要素のみ表示状態になる。

そして、click_flg変数を設定しておくことで、フェードインアウトの処理中にクリックされても不具合を起こさないように処理をしています。

まとめ

正直な話をするとselectboxを使うほうが早いですし、わりと無理な作りになっていると思うので、

「どうしてもdivでselectのような動きを実装したいんだぁぁぁ」

ってときにだけお使いください。

おそまつ!