初心者にも分かる!なアコーディオンの作り方

初心者にも分かる!なアコーディオンの作り方

クリックすると開閉するコンテンツ、いわゆるアコーディオンの作り方を、初心者が1から作れるように説明します。難しいようでシンプルなので、15分あれば、確実に理解できます。当サイトでは、カテゴリを選択するサイトマップで利用しています。

サンプルデモ

デザインなしのアコーディオン
デザインなしのアコーディオン

今回、作るアコーディオンのサンプルデモです。「メニュー1」「メニュー2」をクリックすると、それぞれの子メニューが開閉します。ここでの項目は最低限の2つだけですが、数は、後からいくつでも増やすことができます。あと、デザインは仕組みを理解する上で邪魔なので、排除しちゃってます。記事の最後でダウンロードできるので、あなた自身で好きなようにデザインをして下さいね。

サンプルデモを見る

アコーディオンの仕組み

アコーディオンの仕組みは、とっても簡単で、jQueryのslideToggle()というメソッドを利用しているだけです。

[slideToggle()]とは?

slideToggle()は、「開いている時には閉めて、閉まっている時には開く」という便利な、jQueryのメソッドです。まるで楽器のアコーディオンのようにビヨ〜ンと上下にアニメーションして動作します。

[slideToggle()]の挙動を確認する

HTMLの作成

クリックイベントで挙動を確認してみましょう。まずは適当に、ボタンと開閉する要素の2つを用意します。

HTML

<!-- クリックイベントを設定するボタン -->
<p><a id="acdn-button" class="acdn-button"><b>開閉する</b></a></p>

<!-- 開閉する要素 -->
<p id="acdn-target" class="acdn-content">ターゲットとなる要素</p>

CSS

/* 開閉する要素 */
.acdn-content
{
	width: 200px ;
	height: 200px ;
	background: #D36015 ;
}

なんてことのない、次のようなデザインが出来上がりましたね。まだ単なるデザイン段階なので、「開閉する」をクリックしても、何も起こりません。

開閉する

ターゲットとなる要素

クリックイベントの設定

続いて、「開閉する」というリンクテキスト(#acdn-button)に対して、「開閉する要素(#acdn-target)にslideToggle()を実行する」というクリックイベントを設定してみましょう。

JavaScript

// [#acdn-button]にクリックイベントを設定する
$( '#acdn-button' ).click( function()
{
	// [#acdn-target]に[slideToggle()]を実行する
	$( '#acdn-target' ).slideToggle() ;

} ) ;

それでは、「開閉する」をクリックして、どのような挙動をするのか、確認してみて下さい。上下に「閉じる」「開く」を交互に繰り返すはずです。

開閉する

ターゲットとなる要素

アコーディオンの仕組み

先ほどのサンプルで既に「これならもう、アコーディオン作れるなっ」という人がいるんじゃないでしょうか。アコーディオンの仕組みとはシンプルなもので、「トリガーとなるボタン」と「ターゲットとなるコンテンツ」のペアを作って、slideToggle()を実行するクリックイベントを設定するだけのことです。1つ1つのトリガーに対して、新しく処理を記述していくのは大変なので、あとは、「いかに拡張性のあるプログラムにするか」という工夫をするのみです。それを次章で紹介します。

制作方法

アコーディオンの仕組みを理解できたら、早速、作成してみましょう。

HTML部分の作成

まずは、HTML部分を作成しましょう。シンプルに、ul要素で構成しましょう。まずは、土台となる親メニューを作ります。親メニューには、クリックイベントを設定するための、共通のクラス属性値(サンプルではsyncer-acdn)を付けておいて下さい。

HTML

<ul>
	<li><p><a class="syncer-acdn">メニュー1</p></li></a>
	<li><p><a class="syncer-acdn">メニュー2</p></li></a>
</ul>

続いて、それぞれのli要素の中に、子メニューを入れましょう。子メニューもここでは、ul要素で構成します。次のような形になります。親メニュー名をクリックすると、子であるul要素に対してslideToggle()が実行されるというシステムを目指します。

HTML

<ul>
	<li><p><a class="syncer-acdn">メニュー1</a></p>
		<ul>
			<li>子メニュー 1-1</li>
			<li>子メニュー 1-2</li>
		</ul>
	</li>
	<li><p><a class="syncer-acdn">メニュー2</a></p>
		<ul>
			<li>子メニュー 2-1</li>
			<li>子メニュー 2-2</li>
		</ul>
	</li>
</ul>

トリガーとターゲットを繋ぐ

親メニュー(トリガー)と子メニュー(ターゲット)のペアをいくら増やしても、同じようにプログラムが作動するように、この2つを繋ぎましょう。まず、ターゲットとなるul要素に、一意のID属性値を設定します。サンプルでは、syncer-acdn-01syncer-acdn-02を設定しました。

HTML

<ul>
	<li><p><a class="syncer-acdn">メニュー1</a></p>
		<ul id="syncer-acdn-01">
			<li>子メニュー 1-1</li>
			<li>子メニュー 1-2</li>
		</ul>
	</li>
	<li><p><a class="syncer-acdn">メニュー2</a></p>
		<ul id="syncer-acdn-02">
			<li>子メニュー 2-1</li>
			<li>子メニュー 2-2</li>
		</ul>
	</li>
</ul>

そしてトリガーとなるa要素には、data-targetという属性を追加し、その値には、ターゲットとなる要素のID名を設定します。次の通りですね。

HTML

<ul>
	<li><p><a class="syncer-acdn" data-target="syncer-acdn-01">メニュー1</a></p>
		<ul id="syncer-acdn-01">
			<li>子メニュー 1-1</li>
			<li>子メニュー 1-2</li>
		</ul>
	</li>
	<li><p><a class="syncer-acdn" data-target="syncer-acdn-02">メニュー2</a></p>
		<ul id="syncer-acdn-02">
			<li>子メニュー 2-1</li>
			<li>子メニュー 2-2</li>
		</ul>
	</li>
</ul>

クリックイベントの作成

トリガーとなるa要素をクリックすると、そのdata-targetの値(例えばsyncer-acdn-01)を読み込み、その値と同じ名前のIDを持つ要素に対してslideToggle()を実行する、というプログラムを作成します。これなら、いくらペアが増えても、JavaScriptのコードを改変する必要がなくなるというわけです。

まずは、トリガーに共通して設定されているsyncer-acdnを対象に、クリックイベントを設定します。次の通りですね。

JavaScript

// [.syncer-acdn]にクリックイベントを設定する
$( '.syncer-acdn' ).click( function(){

	// 処理の記述
	// ...

} ) ;

[data-target]を読み込む

次に、クリックした要素($(this))の、data-target属性値を読み込みます。これを任意の変数であるtargetに代入します。

JavaScript

// [data-target]の属性値を代入する
var target = $(this).data( 'target' ) ;

[slideToggle()]を実行する

仕上げです。targetに代入された文字列と同じ名前のID名を持つ要素に対して、slideToggle()を実行します。これで、アコーディオンの完成です。呆気なさ過ぎて時間が余ってしまいましたか?

JavaScript

// [target]と同じ名前のIDを持つ要素に[slideToggle()]を実行する
$( '#' + target ).slideToggle() ;

完成版のコード

完成版のコードです。これだけで、トリガーとターゲットのペアをいくら増やしても、それら全てがアコーディオンになります。ul要素に限らず、div要素でもol要素でも、ルールを守れば、どんな要素にも適用できます。

JavaScript

// [.syncer-acdn]にクリックイベントを設定する
$( '.syncer-acdn' ).click( function()
{
	// [data-target]の属性値を代入する
	var target = $( this ).data( 'target' ) ;

	// [target]と同じ名前のIDを持つ要素に[slideToggle()]を実行する
	$( '#' + target ).slideToggle() ;
} ) ;

サンプルプログラム

素のアコーディオン

記事の冒頭で紹介したものです。下地として利用するのに最適な、余計なデザインを一切施していないアコーディオンコンテンツです。スタイルシートはありません。

HTML

<h2>アコーディオン</h2>
<p>分かりやすいように、デザインを排除したシンプルなアコーディオンです。親メニュー名をクリックすることで、子メニューが開閉します。</p>
<ul>
	<li><p><a class="syncer-acdn" data-target="syncer-acdn-01">メニュー1</a></p>
		<ul id="syncer-acdn-01">
			<li>子メニュー 1-1</li>
			<li>子メニュー 1-2</li>
		</ul>
	</li>
	<li><p><a class="syncer-acdn" data-target="syncer-acdn-02">メニュー2</a></p>
		<ul id="syncer-acdn-02">
			<li>子メニュー 2-1</li>
			<li>子メニュー 2-2</li>
		</ul>
	</li>
</ul>

JavaScript

// DOMを全て読み込んでから処理する
$(function()
{
	// [.syncer-acdn]にクリックイベントを設定する
	$( '.syncer-acdn' ).click( function()
	{
		// [data-target]の属性値を代入する
		var target = $( this ).data( 'target' ) ;

		// [target]と同じ名前のIDを持つ要素に[slideToggle()]を実行する
		$( '#' + target ).slideToggle() ;

		// 終了
		return false ;
	} ) ;
}) ;

デザインされたアコーディオン

デザインありのアコーディオン
デザインありのアコーディオン

アコーディオンに、ある程度のデザインを施したサンプルデモです。JavaScriptは、前項で紹介したものと同じです。

HTML

<h2>アコーディオン</h2>
<p>ある程度のデザインを加えたアコーディオンです。</p>
<ul class="syncer-acdn-parent">
	<li><p><a class="syncer-acdn" data-target="syncer-acdn-03">メニュー1</a></p>
		<ul id="syncer-acdn-03" class="syncer-acdn-child">
			<li><a href="#syncer-acdn-01">子メニュー 1-1</a></li>
			<li><a href="#syncer-acdn-01">子メニュー 1-2</a></li>
			<li><a href="#syncer-acdn-01">子メニュー 1-3</a></li>
			<li><a href="#syncer-acdn-01">子メニュー 1-4</a></li>
			<li><a href="#syncer-acdn-01">子メニュー 1-5</a></li>
			<li><a href="#syncer-acdn-01">子メニュー 1-6</a></li>
			<li><a href="#syncer-acdn-01">子メニュー 1-7</a></li>
		</ul>
	</li>
	<li><p><a class="syncer-acdn" data-target="syncer-acdn-04">メニュー2</a></p>
		<ul id="syncer-acdn-04" class="syncer-acdn-child">
			<li><a href="#syncer-acdn-02">子メニュー 2-1</a></li>
			<li><a href="#syncer-acdn-02">子メニュー 2-2</a></li>
			<li><a href="#syncer-acdn-02">子メニュー 2-3</a></li>
			<li><a href="#syncer-acdn-02">子メニュー 2-4</a></li>
			<li><a href="#syncer-acdn-02">子メニュー 2-5</a></li>
			<li><a href="#syncer-acdn-02">子メニュー 2-6</a></li>
			<li><a href="#syncer-acdn-02">子メニュー 2-7</a></li>
		</ul>
	</li>
</ul>

CSS

/******************************

	デザインあり

******************************/

/* 親の[ul] */
.syncer-acdn-parent
{
	width: 250px ;
	margin: 1.5em 0 0 ;
	padding: 12px 18px ;
	border: 2px solid rgba( 0,0,0, 0.1 ) ;
}

/* 子の[ul] */
.syncer-acdn-child
{
	display: none ;
}

/* 余白設定 */
.syncer-acdn-child ,
.syncer-acdn-parent li ,
.syncer-acdn-parent li p
{
	margin: 0 ;
	padding: 0 ;
}

/* 親と子の[li] */
.syncer-acdn-parent li
{
	list-style: none ;
}


/* 親の[a] */
.syncer-acdn-parent li p a
{
	position: relative ;
	top: 0 ;
	left: 0 ;
}

.syncer-acdn-parent li p a:after ,
.syncer-acdn-parent li p a:hover:after
{
	color: #333 ;
	background: rgba( 0,0,255 , 0.1 ) ;
}

.syncer-acdn-parent li p a:after
{
	position: absolute ;
	top: 50% ;
	right: 12px ;
	content: "開閉" ;
	font-size: .85em ;
	margin-top: -12.5px ;
	height: 17px ;
	line-height: 17px ;
	padding: 4px 8px ;
}


/* 親の[a]と子の[li] */
.syncer-acdn-parent li p a ,
.syncer-acdn-child li
{
	border-bottom: 1px solid rgba( 0,0,0, 0.1 ) ;
}


/* 親と子の[a] */
.syncer-acdn-parent li a
{
	display: block ;
	padding: 8px 0 ;
	font-weight: 700 ;
	text-decoration: none ;
	color: #333 ;
}

.syncer-acdn-parent li a:hover
{
	cursor: pointer ;
	color: #f00 ;
	background: rgba( 0,0,0, 0.1 ) ;
}


/* 子の[a] */
.syncer-acdn-child li a:before
{
	content: "∟" ;
	padding-right: 5px ;
}

このコードの動作を確認する

FAQ形式のアコーディオン

FAQ形式のアコーディオン
FAQ形式のアコーディオン

FAQなどのコンテンツによくある、質問タイトルをクリックすると、回答が表示されるタイプのアコーディオンです。これまでのul要素ではなく、dl要素を使っているのが特徴です。このようなコンテンツも実現します。JavaScriptの内容も、ここまでに紹介したのと全く同じです。拡張性が高いというのは美しいものですね。

HTML

<h2>アコーディオン</h2>
<p>クリックすると回答を見ることができる、Q&A形式のアコーディオンです。質問をクリックすると、回答を見ることができます。</p>

<dl class="syncer-acdn-faq">
	<dt class="syncer-acdn" data-target="syncer-acdn-05">Q. あなたの名前はなんですか?</dt>
		<dd id="syncer-acdn-05">A. 私の名前はまだありません…。</dd>
	<dt class="syncer-acdn" data-target="syncer-acdn-06">Q. 昨日のご飯はなんでしたか?</dt>
		<dd id="syncer-acdn-06">A. 昨日は「さすけ食堂」で黄金鯵を食べました…。</dd>
	<dt class="syncer-acdn" data-target="syncer-acdn-07">Q. あなたが好きな犬の種類はなんですか?</dt>
		<dd id="syncer-acdn-07">A. ダントツで<a href="https://twitter.com/arayutw/status/631488635871735808" target="_blank">黒柴</a>です。</dd>
	<dt class="syncer-acdn" data-target="syncer-acdn-08">Q. 好きな水族館はどこですか?</dt>
		<dd id="syncer-acdn-08">A. 高知県桂浜にある「桂浜水族館」です。砂浜の中にある独特の景観もいいですし、館内の「手作り感」に親しみを覚えるのです。</dd>
</dl>

CSS

/******************************

	Q&A形式

******************************/
.syncer-acdn-faq
{
	margin: 1.5em 0 0 ;
}

.syncer-acdn-faq dt ,
.syncer-acdn-faq dd
{
	margin: 0 0 0 2em ;
	padding: 4px 0 ;
}

.syncer-acdn-faq dt:hover
{
	cursor: pointer ;
	color: #777 ;
}

.syncer-acdn-faq dt
{
	font-weight: 700 ;
}

.syncer-acdn-faq dd
{
	display: none ;
	padding: 12px 0 1.5em 1.5em ;
}

このコードの動作を確認する

ダウンロード

この記事で紹介してきた、各サンプルプログラムを配布しています。あなたのウェブサイトに活用していただければ、記事を書いた者としてこの上ない喜びです。

ファイル一覧

SYNCER00425
accordion-raw.html Download
accordion.js Download
accordion-designed.html Download
accordion-designed.css Download
accordion-faq.html Download
accordion-faq.css Download

ファイル名をクリックすると内容を確認できます。「Download Zip」をクリックするとファイル一式をダウンロードできます。

Download Zip