LoginSignup
0
1

More than 5 years have passed since last update.

jQueryでselectbox風リストの作成と表示・非表示(mouseover/mouseout/clickの挙動)

Last updated at Posted at 2017-02-03

基本のHTMLとCSS

<form>
    <div class="selectbox">
      <p class="selectbox__select">
        <span class="selectbox__select__text">選択してください</span>
      </p>
      <ul class="selectbox__pulldown">
        <li class="selectbox__pulldown__list" param="項目">項目1</li>
        <li class="selectbox__pulldown__list" param="項目2">項目2</li>
        <li class="selectbox__pulldown__list" param="項目3">項目3</li>
        <li class="selectbox__pulldown__list" param="項目4">項目4</li>
        <li class="selectbox__pulldown__list" param="項目5">項目5</li>        
      </ul>
      <input type="hidden" name="selectbox" value="" />
    </div>

    <input type="submit" value="検索">

  </form>
sassファイル
.selectbox{
    display: inline-block;
    zoom: 1;
    position: relative;
    height: 40px;
    font-size: 1.4rem;
    .selectbox__select {
      width: auto;
      height: 40px;
      border: solid #ddd 1px;
      display: inline-block;
      zoom: 1;
      color: #262626;
      text-decoration: none;
      cursor: default;
      margin: 0;
      padding: 10px 10px;
      .selectbox__select__text {
          padding: 0 20px 0 0;
          display: block;
          height: 20px;
          line-height: 20px;
          cursor: default;
      }
    }
    .selectbox__pulldown {
      border: solid #bbb 1px;
      width: auto;
      height: auto;
      position: absolute;
      left: 0;
      top: 28px;
      background: #fff;
      overflow: auto;
      padding: 0;
      z-index: 3;
      .selectbox__pulldown__list {
        width: 100%;
        height: auto;
        border-bottom: solid #bbb 1px;
        padding: 5px 8px;
        display: block;
        &.last-child {
          border: none;
        }
        &:hover, &.selected {
          color: #666;
          background: #eee;
          text-decoration: none;
        }
      }
    }

    /* afterでselectboxの矢印画像を追加 */
    &::after {
      background-image: url(../../images/select-arrow-0.svg); /* ここは自分の好きな画像 */
      background-repeat: no-repeat;
      background-position: center;
      background-size: 100% 100%;
      content: '';
      display: inline-block;
      line-height: 0;
      vertical-align: middle;
      width: 2.14286em;
      height: 100%;
      position: absolute;
      top: 0;
      right: 0;
      pointer-events: none;
    }
  }

mouseoverとmouseoutで自動で表示・非表示

* $(セレクタ).find(セレクタ/obj/element):セレクタ内をfindのカッコ内で選択
* .toggle(引数):引数がtrueで表示、falseで非表示

$('.selectbox').each(function(){ // div.selectboxの数ループ
    var self = $(this);
    var select = $('.selectbox__select',self);
    var pulldown = $('.selectbox__pulldown',self);
    var data = $('input:hidden',self);
    var select_value = $('.selectbox__select__text',select);
    pulldown.hide().children(':last-child').addClass('last-child');

    // div.selectboxにmouseover or mouseout
    self.on('mouseover mouseout',function(e){
        // .selectboxから.selectbox__pulldownを探し、hideにする(初期化)
        self.find('.selectbox__pulldown').hide();

        // e.typeでmouseover/mouseoutを判定
        self.find('.selectbox__pulldown').toggle(e.type=='mouseover');
        self.addClass('select_focus');

      e.stopPropagation();
      return false;
    });


    $('.selectbox__pulldown__list',pulldown).click(function(){
        // タップされたaタグのテキストを取得
        var text = $(this).text();
        // 表示されるテキストを入れ替える
        select_value.text(text);
        // 選択された項目値をinputタグのvalueにセット
        data.val($(this).attr('param'));

        // クラスの削除
        $('.selected',pulldown).removeClass('selected');
        $('.select_focus').removeClass('select_focus');
        $(this).addClass('selected');
        pulldown.hide();
        return false;
    });
});

clickで表示・非表示

$('.selectbox').each(function(){ // selectboxの数ループ
    var self = $(this); // selectbox自身

    // $(セレクタ[, コンテキスト]):引数のコンテキストからセレクタを検索
    var select = $('.selectbox__select',self);
    var pulldown = $('.selectbox__pulldown',self);
    var data = $('input:hidden',self);
    var select_value = $('.selectbox__select__text',select);

    // pulldownをhideしてlast-childにclassを追加
    pulldown.hide().children(':last-child').addClass('last-child');

    // aタグ(.select)がタップされた時
    select.click(function(e){
      // pulldown hide(複数ある場合に役立つ)
      $('.selectbox__pulldown').hide();
      // クリックされたpulldownを表示
      pulldown.show();
      $(this).addClass('select_focus');

      // 親要素へのイベントバブリングをキャンセル
      e.stopPropagation();
      return false;
    });


    $('.selectbox__pulldown__list',pulldown).click(function(){
        // タップされたaタグのテキストを取得
        var text = $(this).text();
        // 表示されるテキストを入れ替える
        select_value.text(text);
        // 選択された項目値をinputタグのvalueにセット
        data.val($(this).attr('param'));

        // selectedクラスの削除
        $('.selected',pulldown).removeClass('selected');
        // select_focusクラスの削除
        $('.select_focus').removeClass('select_focus');
        // 選択された要素にclassを追加
        $(this).addClass('selected');

        return false;
    });

    // bodyをクリックしてpulldownを閉じる
    $('body').click(function(){
        $('.select_focus').removeClass('select_focus');
        $('.selectbox__pulldown').hide();
    });
  });

参考資料

技術評論社
http://gihyo.jp/design/serial/01/jquery-site-production/0012

イベントのバブリング (ここら辺まだ理解できていない)
http://www.tam-tam.co.jp/tipsnote/javascript/post5050.html

0
1
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
0
1