質問項目をクリックするとその回答がビローンと展開するアコーディオン


スポンサーリンク

Q&Aのページなどで質問項目をクリックするとその回答がビローン”と展開される ページってよくありますよね?

一般的には、アコーディオンとよばれるモジュールです。

あれは、どうやっているかといえば、css の id を指定して、そのIDの display 属性を hidden(非表示) にしたり、display(表示)にしたりして実現しています。

たとえば、
Q1、質問
<div id="ans">答え</div>
こんな感じに書いておいて、 最初は、id anser の 表示属性を hide にしてしまいます。

Q1、の領域をクリックされた時 id anser の 表示属性を display にしてあげれば、id anser の領域が表示され、ビローンと伸びて表示される仕組みです。

大雑把に書くと
<input type="button" value="Q1、質問<" onclick="clickBtn1()" />
<div id="ans1">答え</div>
 :
<script>
field_display();
var flip1
function field_display()
{
var ans1= document.getElementById('ans1');
ans1.style.display ="none";
flip1=0;
}
function clickBtn1()
{
var ans1= document.getElementById('ans1');
if(flip1==1){
ans1.style.display ="block";
flip1=0
}else{
ans1.style.display ="none";
flip1=1
}
}
</script>

アコーディオンで問題になるのは、状態の保持とアクションのフックです。

以下を例としてアコーディオンの説明します。
<div id="ans1">Q1、質問</div>
<div id="ans1">答え</div>


アコーディオンを実現するためのアクションフック


アクションのフックもいろいろな方法が考えられ例のようにボタンのクリックアクションをトリガーにするのが一番簡単。

よく使われるのが、Jquery を使う方法です。

jQuery のアクションフック


jQuery のアクションフックは、以下のような書式で使用できます。

要素.on( イベント名, 関数 )

前述の例で que1 のクリックイベントをフックするなら
<script>
    $('que1').on('click', function() {
        clickBtn1();
    })
</script>

イベントは、複数指定できるので

<script>
    $('que1').on('click mouseover', function() {
        clickBtn1();
    })
</script>
といった方法も考えられます。

イベント一覧

イベント名内容
changeフォーム部品に変化があった
click要素がクリックされた
blur / focus要素にフォーカスが当たった(focus) / 外れた(blur)
loadドキュメントが読み込まれた
resizeウィンドウサイズが変わった
scroll画面がスクロールした
keyup / keypressキーボードが押された時(keypress)、離された時(keyup)
mouseup / mousedownマウスのボタンが押された(mousedown)、離された(mouseup)
mousemove指定の要素内でマウスが乗った
submitフォームが送信された
errorJavaScriptエラーが発生した





スポンサーリンク





アコーディオンの状態保存


次に問題になるのが状態の保存です。
前述のように変数に状態を保存するのがプログラムとしては基本ですけど、javascriptでは、slideToggleという便利なものが存在しています。

これは、呼び出すたびにフリップフロップ(状態が交互に変わる)を実現します。
 

質問項目をクリックするとその回答がビローン”と展開する方法まとめ


<ul>

<li><p><a class="que" data-target="que1">メニュー1</a></p>
<ul id="que1">
<li>回答1</li>
</ul>
</li>

<li><p><a class="que" data-target="que2">メニュー2</a></p>
<ul id="que2">
<li>回答2</li>
</ul>
</li>

</ul>

<script>
$(function()
{
	$( '.que' ).click( function()
	{
		var target = $( this ).data( 'target' ) ;
		$( '#' + target ).slideToggle() ;
		return false ;
	} ) ;
}) ;
</script>

class que のクリックで click(function が起動します。
que の data-target を読み込んで、それで操作する対象の id とします。
slideToggle によって、その 対象を消したり、表示させたりします。

この記述で失敗する多くの原因は、jQuery を先に読み込ませていた場合に起こります。

このソースを表示してから JQuery を呼び出すようにします。

前述ソース
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>

読み込みの順番がおかしかったりすると デベロッパーツールで
Uncaught TypeError: $ is not a function
といったエラーメッセージが表示されることになります。


自分自身をビローンと伸ばすアコーディオンの実装は、details,summary を使うとすこぶる簡単


自分自身をビローンと伸ばすアコーディオンの実装は、details,summary を使うと JavaScriptを使用する必要がありません。

こんな感じ。
<details>
    <summary>質問1</summary>
    回答1
</details>
<details>
    <summary>質問2</summary>
    回答2
</details>

三角形のCSSも使ってません。

もちろん、デザイン的にこのままだとみっともないのでスタイルシートを使ってデザインを整えます。

JavaScript を使わない分、配置する場所にも悩まずに使えるのが便利です。

質問1 回答1
質問2 回答2

スポンサーリンク