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

目次

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

<div class="container">
   <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>
  </div>
HTML
.container {
  max-width: 600px;
  margin: 100px auto;
}

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

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

.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;
}
CSS
$(function() {
  $('.question').click(function() {
    $(this).toggleClass('open');
    $(this).next().slideToggle();
    $('.question').not($(this)).next().slideUp();
    $('.question').not($(this)).removeClass('open');
  });
});
JavaScript

出力結果

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

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

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

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

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

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

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

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

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

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

<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>
HTML
.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;
}
CSS

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() {
  //処理内容
});
JavaScript

クリックイベントの作成

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

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

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

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

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

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

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

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

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

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

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

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

出力結果

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

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

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

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

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

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

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

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

出力結果

しかし、質問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'); //クリックされていない質問の矢印は元に戻す
  });
});
JavaScript

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

出力結果

TOP