HTML
JavaScript
jQuery

複数項目の詳細表示 / 非表示を、JQuery5行で実装する

slideToggle.mov.gif

よくあるこういうリスト形式の詳細表示非表示をJQuery5行で実装しました。

HTML・CSSはこんなかんじです。

pulldown.html
<head>
  <link rel="stylesheet" type="text/css" href="./stylesheet.css">
  <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
  <script src="./pulldown.js"></script>
</head>

<body>
  <div class="item1 pulldown">
    <div class="pulldown-head" data-slide="slide1">ここを押すと表示 / 非表示</div>
    <div class="pulldown-body slide1">詳細部分1</div>
  </div>

  <div class="item2 pulldown">
    <div class="pulldown-head" data-slide="slide2">ここを押すと表示 / 非表示</div>
    <div class="pulldown-body slide2">詳細部分2</div>
  </div>
</body>
css.stylesheet.css
.pulldown {
  width: 300px;
  margin: 0 0 10px 20px;
}

.pulldown-head {
  background-color: lightgreen;
  height: 40px;
}

.pulldown-body {
  display: none;
  background-color: lightgray;
  height: 200px;
}

当然、pulldown-headクラスにクリックイベントをバインドしてpulldown-bodyをスライドダウンする記述だと、ひとつのpulldown-headをクリックした時に全ての要素のbodyが表示されてしまいます。

だからといって要素1つ1つにjsを書いていては冗長すぎるので、以下のようにしました。

まずHTML追記。

pulldown.html
<div class="pulldown-head" data-slide="slide1">ここを押すと表示 / 非表示</div>
<div class="pulldown-body slide1">詳細部分1</div>

<div class="pulldown-head" data-slide="slide2">ここを押すと表示 / 非表示</div>
<div class="pulldown-body slide2">詳細部分2</div>

js5行書く。

pulldown.js
  $(function(){
    $('.pulldown-head').on('click', function(){
      $('.' + $(this).data('slide')).slideToggle(700);
    })
  })

解説

ポイント1:カスタムデータ属性経由で詳細部分を取得

まず詳細部分のHTMLタグに、その項目特有のクラス名(ここではそれぞれslide1, slide2)を付与します。
次に、head部分のHTMLタグにカスタムデータ属性(ここではdata-slide)を付与し、その値に上で定義したクラス名を入れます(slide1, slide2)

こうすることで、js側で、クリックされた要素のdata属性の値がクラス名である要素を取得することが可能になります。

//data-slideがslide1の要素をクリックした時
$('.' + $(this).data('slide'))==$('slide1')

//data-slideがslide2の要素をクリックした時
$('.' + $(this).data('slide'))==$('slide2')

なお、このときJQueryのセレクタで外側をクォーテーションマークで囲む必要はないようです。

ポイント2:slideToggle()

名前の通り、要素をスライド表示・非表示するslideUp(), SlideDown()と、表示非表示を交互に行うtoggle()がこれひとつでできちゃうお得なセット。
もはや解説不要です。

補足

スライド表示・非表示に加えて同時に他の動きをさせたい(たとえば詳細部分の文章をfadeするとか)場合、head部分のカスタムデータ属性を増やして同じように記述すればオッケーです。
fadeToggleもあるよ、、!

pulldown.html
<div class="pulldown-head" data-slide="slide1" data-fade="fade1">ここを押すと表示 / 非表示</div>
<div class="pulldown-body slide1">
  <p class="fade1">詳細部分をフェードイン / アウト</p>
</div>
pulldown.js
  $(function(){
    $('.pulldown-head').on('click', function(){
      $('.' + $(this).data('slide')).slideToggle(700);
      $('.' + $(this).data('fade')).fadeToggle(700);
    })
  })

失敗したこと

最初、クリックされた要素の兄弟要素を取得してそれをスライドさせる処理を書いたんですが、同じクラス名が複数存在している場合うまく動かないみたいでした。

おしまい

何かのお役に立てば・・・。