【jQuery】要素をひとつだけ開くアコーディオンの実装方法(他は閉じる)

jQuery
記事内に商品プロモーションを含む場合があります。

jQueryを使ってクリックした要素をひとつだけ開くアコーディオンメニューの作り方を解説します。

下記サンプルは、例えば「質問1」を開いたまま「質問2」をクリックすると、「質問1」は閉じて「質問2」の一つだけが開きます。

この記事では、こんなアコーディオンメニューの作り方を解説します。

スポンサーリンク

アコーディオンメニューをひとつだけ開くjQueryの書き方

jQueryのコードはこちらです。

$(function() {
  $('.question').click(function() {
    $(this).toggleClass('open');
    $(this).next().slideToggle();
    $('.question').not($(this)).next().slideUp();
    $('.question').not($(this)).removeClass('open');
  })
});

ポイントは5行目と6行目のnot($(this))で、これが「一つだけ開いて残りは閉じる」を実現しています。

では、詳しく解説していきますね。

スポンサーリンク

jQueryでひとつだけ開くアコーディオンメニューを作ってみよう

では、冒頭でご紹介したサンプルのアコーディオンを一緒に作ってみましょう。

アコーディオンの見た目を作る

アコーディオンメニューの見た目となるHTMLとCSSはこちらです。

HTML

<div class="accordion">
   <p class="question">質問1</p>
   <p class="answer">
      Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut 
   </p>
</div>
<div class="accordion">
   <p class="question">質問2</p>
   <p class="answer">
      Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut 
   </p>
</div>
<div class="accordion">
   <p class="question">質問3</p>
   <p class="answer">
      Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut 
   </p>
</div>

CSS

.accordion {
  margin-top: 20px;
  border: 1px solid gray;
}

.question {
  font-size: 20px;
  font-weight: bold;
  padding: 10px;
  background-color: gray;
  color: #fff;
  position: relative;
}

.question::before {
  position: absolute;
  font-family: 'Font Awesome 5 Free';
  content: '\f13a';
  font-weight: 900;
  right: 20px;
  transition: 0.3s;
}

.question.open::before {
  transform: rotate(180deg);
}

.answer {
  padding: 10px;
  display: none;
}

HTMLとCSSの解説

質問をquestion、答えをanswerとし、それらをaccordionで囲ってペアを作成しています。今回は質問1~3まであるので、ペアは3つです。

各質問の右にある矢印は、Font AwesomeのアイコンをCSSの疑似要素で表示し、クリックすると(=openクラスが付くと)180度回転するよう設定しています。こちらは後ほどjQueryで制御します。

answerにはあらかじめdisplay:none;を設定し、非表示にしています。こちらも表示・非表示をjQueryで実装していきます。

jQueryでアニメーションを付ける

アコーディオンメニューの見た目が完成したので、いよいよjQueryで「ひとつだけ開いて残りは閉じる」アニメーションを作っていきましょう。

jQueryの実行予約

まずはjQuery実行予約を記述します。

これは「HTMLの読み込みが完了したら処理を開始してね」というjQueryお決まりの記述なので、忘れず書きましょう。

$(function() {
  //処理内容
});

クリックイベントの作成

次にクリックイベントを作成します。

今回のアコーディオンは「質問をクリックしたら」がトリガーなので、クリック対象はquestionクラスですね。

クラス名なのでquestionの前に「.(ピリオド)」を忘れずに付けましょう。

$(function() {
  $('.question').click(function() {
   //クリックしたときのイベント
  });
});

クリックイベント①:矢印を回転

質問をクリックしたときの処理を書いていきます。

まずは、各質問の右にある矢印の向きを変えるアニメーションを実装しましょう。

CSSであらかじめ「questionクラスにopenクラスを付与すると180度回転する」という指示を書いていますので、こちらを活用します。

クラスの付け外しにはtoggleClassを使うと便利です。クリックすると指定のクラスが付与され、再度クリックするとクラスが外れます。

なお、thisを使うと'.question'の記述重複を避けることができます。

$(function() {
  $('.question').click(function() {
    $(this).toggleClass('open'); //thisは'.question'のこと
  });
});

各質問をクリックすると、矢印が180度回転するようになりました。

クリックイベント②答えを表示

次に、質問をクリックしたときに答え(answer)を表示させるアニメーションを実装します。

現在、答えであるanswerはdisplay:none;で非表示になっているので、display:block;にすれば表示できそうです。

しかし、これだとパッと開いてパッと消える感じで、見栄えがカッコ良くありません。

そこでslideToggleを使うと、上下にスライドするように表示・非表示が切り替わるのでお洒落になります。

表示・非表示を切り替える対象はクリックした質問の次の要素(=answer)なので、next( )を使い下のように表現します。

$(function() {
  $('.question').click(function() {
    $(this).toggleClass('open');
    $(this).next().slideToggle(); //$(this).next():クリックした質問のanswerのこと
  });
});

質問をクリックすると、対応する答えが表示されるようになりました。

しかし、質問1の答えを開いたまま質問2を開いてみると、質問1は開きっぱなしですね。

今からこれを修正します。

クリックイベント③1つだけ開くように調整

最後に、クリックした要素1つだけを開いて、残りは閉じるように調整しましょう。

今回、表示させたいのはクリックした質問の答えだけなので、クリックしていない質問は非表示にする命令を書けば良さそうです。

not( )を使うと指定の要素を除外できるので、下の記述を行うとクリックされていない要素はすべてslideUp(スライドしながら非表示)にできます

同様に、クリックされていない要素のopenクラスも外して、矢印を元に戻す処理も書いておきましょう。

$(function() {
  $('.question').click(function() {
    $(this).toggleClass('open');
    $(this).next().slideToggle();
    $('.question').not($(this)).next().slideUp(); //クリックされていない質問の答えは非表示
    $('.question').not($(this)).removeClass('open'); //クリックされていない質問の矢印は元に戻す
  });
});

これで、クリックした要素をひとつだけ開くアコーディオンメニューが完成しました。