【jQuery】もう迷わないアコーディオンの設置方法

アコーディオンの設置をJavaScriptで書く。ということは難しい!と思っていませんか?

実はjQueryでアコーディオンを設置するとコードはたったの7行で設置できます!

アコーディオンを設置しようと思ったんだけど難しくて...。簡単な方法ないかな?

HTMLとCSSだけできるデザイナーさんでも jQueryでサクっと実装できるので、jQueryのアコーディオンの設置方法をぜひ身につけていきましょう。

前提知識

HTML、CSSが理解できている人

まずは完成イメージ

このような感じで、Qの箇所をクリックするとAの箇所がアニメーションで出てくる仕様です。その際はQのアイコンも回転するように設置します。

jQureyのアコーディオンを実装しよう

ファイル構造はこのような感じで作っております。基本的にはフォルダなどには入れず、並列で各ファイルを並べております。

まずはHTMLのサンプルを作っていきます

HTMLはこんな感じで書いていきます。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>jQueryでアコーディオン</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>

  <div class="faq" data-accordion="box">
    <div class="faq__question" data-accordion="title">Q アコーディオンはどうやって作ればいいでしょうか?<span class="faq__toggleIcon"></span></div>
    <div class="faq__answer" data-accordion="item">A jQueryで簡単に設置できます。</div>
  </div>

  <!-- jQueryCDN -->
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script>
  <!-- js読み込み -->
  <script src="index.js"></script>
  
</body>
</html>
HTMLのポイント

①jQueryCDNを読み込んだ後に、今回書くJSのファイル(index.js)を読み込む必要があります。この順番を間違うとJSのコードが動かないので注意が必要になります。

②JSを付加する要素にはわかりやすくdata属性で指定していきます。運用面でCSSクラスと分離してdata属性を使うと後々わかりやすいのでおすすめ。

アイコンはCSSで作っております(サイトに合わせて調整してください)。

CSSのサンプルを書いていきます

.faq {
  max-width: 600px;
  width: 100%;
}

.faq__question {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  background: #000;
  color: #fff;
  padding: 10px 20px;
}

.faq__toggleIcon {
  display: block;
  width: 15px;
  height: 15px;
  position: relative;
}

.faq__toggleIcon::before {
  content: "";
  display: inline-block;
  height: 2px;
  width: 9px;
  background: #fff;
  transform: translateY(50%) rotate(45deg);
  position: absolute;
  top: 50%;
  left: 0;
}

.faq__toggleIcon::after {
  content: "";
  display: inline-block;
  height: 2px;
  width: 9px;
  background: #fff;
  transform: translateY(50%) rotate(-45deg);
  position: absolute;
  top: 50%;
  right: 0;
}

.faq__answer {
  display: none;
  padding: 10px 20px;
  background: #ddd;
}
CSSのポイント

①アイコンをフレックスボックスのspase-betweenで端に寄せで、テキストとアイコンがレスポンシブで、引っ付かないように間の余白をgap: 10pxで余白を確保しています。

②アコーディオンの開くanswer部分は非表示にしておく(display:none)。

ここまで来たら表示を確認してみましょう。

上記の感じになってたら、それでOKです。またクリックしても動かないことを確認しておきましょう。

jQueryを書いていきましょう。

ここからは少しわかりにくいところかもしれないので、細かく進めていきます。

今回使う jQueryのメソッド

find() 取得した要素からみての子要素を検索して取得する

closest() 取得した要素からみて親要素を取得

on() イベントを登録できる今回でいうとclickイベントを第一引数で登録できます

slideToggle() 取得した要素をスライドアニメーションで表示非表示を繰り返す(表示していたら、非表示)

toggleClass() クラスの付け外しができます(指定したクラスがあれば外す、なければ付加する)

index.jsにjQueryを書いていきます。

$(function() {
  /* ここに処理を書く */
});

jQueryを書く場合はjsファイル内で上記のように書きます。これは今からjQueryを書きますよ!という宣言みたいなもので、こちらのコードで囲わないとちゃんとjQueryが動かないので気をつけていきましょう。
詳しく$(function(){})を知りたい人はこの記事がわかりやすかったです。

次はこの中に処理を書いていきましょう。

$(function() {
  /* ここに処理を書く */
  $('[data-accordion="title"]').on('click', function() {
    $(this).closest('[data-accordion="box"]').find('[data-accordion="item"]').slideToggle();
  });

});

まず$('')でdata属性を囲むと、そのdata属性のHTMLを取得できます。今回はdata-accordion="title"のHTML要素を取得します。

クリックする要素にまずはクリックイベントを付けていきます。今回でいうとdata-accordion="title"のHTMLにイベントを付加します。イベントをつけるにはon()メソッドでclickと登録します。(これでクリックできるようになる)

クリックした後の処理はfunction(){}の中に書いていきます。いっぺんに書いてしまったのですが、下記のfunction(){}の中のコードを説明していきます。

 $(this).closest('[data-accordion="box"]').find('[data-accordion="item"]').slideToggle();

$()の中にthisと書いていますが、thisはイベントを発生した要素のことを指しますので、今回でいうとクリックされたHTMLのdata-accordion="title"のことを指します。「this」と書いて取得ことで、クリックした要素だけを取得できるので実はめっちゃ便利な書き方です。
thisについて詳しく知りたいならこちらの記事がわかりやすかったです

thisでクリックした要素だけを取得して、ドットで繋いでclosest('[data-accordion="box"]')となっていますが、こちらはクリックした要素の親要素にあたるdata-accordion="box"を検索して取得してくれます。この時点ではクリックした要素の親要素のdata-accordion="box"を取得しています。

次はドットで繋いでfind('[data-accordion="item"]')となっていますが、現時点ではクリックした要素の親要素のdata-accordion="box"を取得しているので、そこからドットで繋いでfind()は子要素の検索して取得するので、最終的にクリックした要素の親のdata-accordion="box"内の子要素のdata-accordion="item"を取得するということになります。

動きのイメージはこのような感じです。

ちょっとわかりづらいかもですが、data-accordion="box"を経由してクリックした要素の隣の要素を取得しております。これでアコーディオンを2つ、3つと追加していっても他のアコーディオンに影響を与えないように独立して機能させることができます。

このようにドットで処理をつなげて、1行でたくさんの処理ができるのはjQueryの強みになります。

現時点で確認すると、これでもう下記のようにアコーディオンとして動作しているのではないでしょうか?

まだ右側にあるアイコンが動いていないので、それを動くように調整していきたいと思います。

クリックした時にアイコンを動かす

少しCSSを追加します。

.faq__toggleIcon {
  transition: transform .3s ease-in-out;
}

.faq__question.is-open .faq__toggleIcon {
  transform: rotate(180deg);
}

style.cssのどこでもいいので上記を追加します。

アイコンはクラスを付加して動かす

クリックした時の動作をCSSに追記しました。みればわかるかもですが、is-openというクラスを付加してアイコンを動作させています。

クラスを付加するJSを追記

クラスを付加するJSを追記します。

$(function() {
  /* ここに処理を書く */
  $('[data-accordion="title"]').on('click', function() {
    $(this).closest('[data-accordion="box"]').find('[data-accordion="item"]').slideToggle();
    $(this).toggleClass('is-open');
  });
});

今回もthisを使い、ドットで繋いでtoggleClass('is-open')としています。
toggleClass()は指定したクラスがあれば削除する、なければ付加するという動きをしてくれます。なので今回クリックイベントの中で書いているので、クリックするたびにクラスの付け外しをしてくれることになります。

こちらで動作を確認してみましょう。
下記のように問題なく動作していれば完了となります。

こちら複数のアコーディオンにも対応している仕様なので、複数に変更してみましょう。

HTMLはこのような感じです。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>jQueryでアコーディオン</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>

  <div class="faq" data-accordion="box">
    <div class="faq__question" data-accordion="title">Q アコーディオンはどうやって作ればいいでしょうか?<span class="faq__toggleIcon"></span></div>
    <div class="faq__answer" data-accordion="item">A jQueryで簡単に設置できます。</div>
  </div>
  
  <div class="faq" data-accordion="box">
    <div class="faq__question" data-accordion="title">Q アコーディオンはどうやって作ればいいでしょうか?<span class="faq__toggleIcon"></span></div>
    <div class="faq__answer" data-accordion="item">A jQueryで簡単に設置できます。</div>
  </div>
  
  <div class="faq" data-accordion="box">
    <div class="faq__question" data-accordion="title">Q アコーディオンはどうやって作ればいいでしょうか?<span class="faq__toggleIcon"></span></div>
    <div class="faq__answer" data-accordion="item">A jQueryで簡単に設置できます。</div>
  </div>
  

  <!-- jQueryCDN -->
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script>
  <!-- js読み込み -->
  <script src="index.js"></script>
  
</body>
</html>

CSSは.faqのクラスにmargin-top: 20px;を設置します。

.faq {
  max-width: 600px;
  width: 100%;
  margin-top: 20px;
}

これで表示してみて、アコーディオンを増やしても独立してちゃんと動いていれば、成功です。

もしちゃんと動かない場合は、各ファイルをダウンロードできるようにしておきますので、直接コードを確認して、再確認していただければと思います。

もし、うまくいかない実装などありましたら、下記からご相談いただけましたらありがたいです。

前にjQueryではなく、素のJavaScriptを使ってアコーディオンの作り方の記事も書いてますので、素のJavaScriptも気になるという人はこちらからどうぞ!

この記事を書いた人

アバター

トノムラマサシ

masashi
Webサイト屋兼ブロガー|過去に企業常駐などを経て現在はフリーランスでディレクションとコーダーとして活動しております。JS大好きなのでJSの仕事依頼お待ちしております。京都在中で5人家族。