【JQuery】アコーディオンをslideToggleでサクッと実装!

【JQuery】コピペOK!アコーディオンをslideToggleでサクッと実装!

JQueryでアコーディオン(クリックで開閉)の動きを実現するには色々な方法がありますが、今回はslideToggleを使ったシンプルな方法です。コピペでどうぞ。

slideToggleを使ったアコーディオンのサンプル

ここに1つ目の質問文が入ります。

ここに1つ目の回答が入ります。

次に2つ目の質問文が入ります。次に2つ目の質問文が入ります。

次に2つ目の回答が入ります。次に2つ目の回答が入ります。

最後に3つ目の質問文が入ります。最後に3つ目の質問文が入ります。最後に3つ目の質問文が入ります。

最後に3つ目の回答が入ります。最後に3つ目の回答が入ります。最後に3つ目の回答が入ります。

コードはこちら

<!-- JQuery本体の読み込み(既に読み込んでいる場合は不要) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<dl class="faq-list">
  <dt class="faq-ttl"><p>ここに質問文が入ります。</p></dt>
  <dd class="faq-content"><p>ここに回答が入ります。</p></dd>
  <dt class="faq-ttl"><p>ここに質問文が入ります。</p></dt>
  <dd class="faq-content"><p>ここに回答が入ります。</p></dd>
</dl>
$('.faq-ttl').click(function(){
  $(this).next('.faq-content').slideToggle();
  $(this).toggleClass('is-active');
});
.faq-ttl {
  position: relative;
  padding: 15px 9% 15px 15px;
  background-color: #fff;
  cursor: pointer;
}
.faq-ttl p,
.faq-content p {
  display: flex;
}
.faq-ttl p::before {
  content: 'Q.';
  display: inline-block;
  margin-right: 1em;
}
.faq-content + .faq-ttl {
  margin-top: 25px;
}
.faq-content {
  display: none;
  margin-top: 10px;
  margin-left: 0;
  padding: 10px 15px;
}
.faq-content p::before {
  content: 'A.';
  display: inline-block;
  margin-right: 1em;
  color: red;
}

/* 「+」を追加 */
.faq-ttl::before,
.faq-ttl::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  right: 4%;
  width: 12px;
  height: 1px;
  margin: auto;
  background-color: #000;
}
.faq-ttl::after {
  transform: rotate(90deg);
  transition: .3s;
}
/* クリックしたときに「+」を「−」に変更 */
.faq-ttl.is-active::after {
  transform: rotate(180deg);
}

今回のサンプルではCSSの疑似要素で「Q.」「A.」の文字と、「+」と「-」の記号を追加しています。

【ざっくり解説】アコーディオンの仕組み

slideToggleとは?

まずJQueryにはslideDownslideUpというメソッドが存在します。
●slideDown…スライドしながら表示する(=開く)
●slideUp…スライドしながら非表示にする(=閉じる)

この2つはあくまでも「開く」「閉じる」という単体の動きのため、これらを使って開閉式のメニューを作ろうとすると「まずif文を使って要素が開いているか閉じているかを判定して、開いていたらslideDownを…」といったコードを書く必要があります。

そんな中今回使ったslideToggleは、これ1つでボタンをクリックする度に「開く」と「閉じる」を交互に行ってくれるというとても便利なメソッド。if文などを使わなくてもこれ1つで開閉の動きを実装できます。

クリックされた要素に隣接している要素だけを開く

今回はQをクリックしたときにその次のAだけを開きたいので、クリックされたfaq-ttlつまり$(this)の、次の要素であるfaq-contentをnextメソッドで指定しています。このように指定せず下記のダメな例↓のようにすると、すべてのAが開いてしまうことになります。

// ○ クリックされたQの次にあるAだけをスライド表示or非表示
$('.faq-ttl').click(function(){
  $(this).next('.faq-content').slideToggle();
});

// × これだとQがクリックされたときに全てのAが開いてしまう
$('.faq-ttl').click(function(){
  $('.faq-content').slideToggle();
});

Qにis-activeクラスを付与する

今回のサンプルではQをクリックしたときに「-」を「+」に変更したいため、Qにis-activeクラスを付けています。Qに何の変化も持たせない場合はこの行は必要なし。

$(this).toggleClass('is-active');

ちなみに「toggle」って何?

トグルとは、留め釘、ダッフルコートの棒状のボタンなどの意味を持つ英単語。ITの分野では、同じ操作や処理によって二つの状態が交互に切り替わるような仕組みのことをこのように呼ぶ。

トグル 【toggle】 – IT用語辞典 e-Words

文字で見るとピンと来ないかもしれませんが「toggle button」で画像検索してみると「あ、これか」と分かるはず。クリックする度にON/OFFが切り替わるものを「トグルボタン」と言います。

そしてJQueryでメソッド名にtoggleと付いていたら「これ1つで何かの状態を交互に切り替えてくれるもの」。例えばサンプルコードに出てきたtoggleClassは「クラス名を付ける」「クラス名を外す」(addClass、removeClass)を交互におこなってくれるメソッドです。

まとめ

アコーディオンの動きは本当によく使うので、ひとまずslideToggleでのやり方を覚えておくと便利です。