【jQuery】クリックで開閉するアコーディオンメニュー7種

【jQuery】クリックで開閉するアコーディオンメニュー7種

jQueryのslideToggleを使った、クリックで開閉するアコーディオンメニュー(開閉パネル)を、7種類実装しました。
クリックしたときに開いたままにしておくものや、開いたアコーディオンメニュー以外は自動で閉じる、最初から開いておく、閉じるボタンで閉じる、多階層のアコーディオンメニュー、アンカーリンクをクリックで、スクロール&該当アコーディオンメニューの開閉などのサンプルです。

ナビゲーションメニュー関連記事

アコーディオンメニューとは

ボタンとなる項目名をクリックすることで、隠れているコンテンツの情報を表示させるものです。その項目名を再度クリックすると、表示されていた画面はまた元のように隠れます。
コンテンツのを折りたたんで隠すことができるので、多階層のアコーディオンメニューを使うことで、ページ全体を確認してから、段階的にコンテンツを表示させることができるようになり、ユーザビリティが向上します。
表示領域が小さいスマホでは、アコーディオンメニューを使うことで情報をコンパクトにまとめることができます。

アコーディオンメニューのhtml

基本のhtmlはこれだけ!
h3が開閉ボタン、pが開閉する要素になってます。デモの5・6・7はulになってますが、pをulに変えるだけです!
今回はデモのためにあえてbtn-とopen-のクラスがjQuery用、
open_h3とinfo/ul_openのクラスがcss用につけてありますので、使用の際は適宜変更してください!そのままでも使えますよ。

html


<h3 class="open_h3 btn-3">BRAND INFO</h3>
<p class="info open-3">テキスト</p>

高さ指定ができていないアコーディオンメニューの挙動

1.高さ指定なしのデモを見てください。開くときに最後の方が、ガクッとなってなめらかに動いてないのがわかります。

See the Pen LYNzaWz by むぅ (@mugenweb) on CodePen.dark

1.アコーディオンメニューの基本形

2.高さ指定ありを見るとなめらかに動いていますね!
1.のガクっとする問題の原因は「高さの指定がしてない」からでした。
解決策としては、必ず開閉する要素に高さを設定しましょう。
それぞれの要素によって、高さが一律ということはあまりないと思うので、jQueryで高さを指定する方法がいいのかと思います。

開閉状態を表す、上△と下△はcssの疑似要素で制御しています。今回は三角でやっていますが、cssのcontentをプラスとマイナスでやってもいいですね。

jQueryでcssの疑似要素contentを変更する方法については下記で解説しています。

jQueryでcssの:before・:afterの疑似要素のstyle・contentを変更する
jQueryでcssの「:before」、「:after」などの疑似要素のstyleを変更する方法です。 色や背景などのデザインだけでなく、contentの内容も変更できます。 css関連記事 ...

See the Pen MWyExry by むぅ (@mugenweb) on CodePen.dark

JavaScript

//高さ指定
$('.open-2').each(function(){
    $(this).css("height",$(this).height()+"px");
});
//開閉要素を隠す
$('.open-2').hide();
//ボタン要素が押されたら
$('.btn-2').click(function () {
	//現在の状況に合わせて開閉
    $('.open-2').slideToggle('slow');
    //現在の状況に合わせてクラスをつける
    $(this).toggleClass('active');
});

css

.wrap{
    width: 800px;
    padding: 10px 20px;
    border: 1px solid #000;
}
h3.open_h3{
    border-bottom: 1px dotted #a9a9a9;
    cursor: pointer;
    margin: 0;
}
.open_h3:after, 
.open_h3.active:after {
    font-size: 22px;
    margin-left: 20px;
}
.open_h3.active::after {
    content: "▲";
}
.open_h3::after {
    content: "▼";
}
.info{
    font-size: 13px;
}

JavaScriptのコードの2~4行目でそれぞれ高さを取得してその高さを指定しているので、内容によって高さが可変になります。
slideToggleは要素が表示されているときはslideUpの動きで隠し、要素が表示されていないときはslideDownの動きで表示します。

toggleClassはクラスがついているときはクラスを消し、クラスがついていないときはクラスをつけてくれます。

このふたつがあればできちゃいますね!クラスは見た目の変更だけですけど。
これで基本形ができたので応用していろんなパターンを作っていきます!

2.複数開くアコーディオンメニュー(開いたまま)

See the Pen jOqGJxP by むぅ (@mugenweb) on CodePen.dark

JavaScript

$('.open-3').each(function(){
    $(this).css("height",$(this).height()+"px");
});
$('.open-3').hide();
$('.btn-3').click(function () {
    $(this).next('.open-3').slideToggle('slow');
    $(this).toggleClass('active');
});

基本的には2のサンプルと同じですが、今回は開く要素が複数あるので、$(this).next(‘.open-3’).slideToggle(‘slow’);としています。これでクリックされた要素の次の.open-3を動かしています!
ここでは、他の開閉メニューをクリックしても、開いている要素は閉じずに、開いた状態を保持します。

3.複数開くアコーディオンメニュー(他は自動で閉じる)

See the Pen
zYqEbaw
by むぅ (@mugenweb)
on CodePen.

JavaScript

$('.open-4').each(function(){
    $(this).css("height",$(this).height()+"px");
});
$('.open-4').hide();
$('.btn-4').click(function () {
    $(this).next('.open-4').slideToggle('slow').siblings('.open-4').slideUp('slow');
    $(this).siblings('.btn-4').removeClass('active');
    $(this).toggleClass('active');
});

3のサンプルに.siblings(‘.open-4’).slideUp(‘slow’);を追加しています。
.siblings(‘.open-4’)で兄弟要素を操作して.slideUp(‘slow’);で全て隠しています。

ここでは、他の開閉メニューをクリックすると、今開いている要素はは自動で閉じられ、開くときは1つだけの状態を保持します。

4.複数開くアコーディオンメニュー(最初のメニューだけ開いておく)

See the Pen qBZPvyx by むぅ (@mugenweb) on CodePen.dark

JavaScript

$('.open-5').each(function(){
        $(this).css("height",$(this).height()+"px");
});
$('.open-5:not(:first)').hide();
$('.btn-5').click(function () {
    $(this).next('.open-5').slideToggle('slow').siblings('.open-5').slideUp('slow');
    $(this).siblings('.btn-5').removeClass('active');
    $(this).toggleClass('active');
});

4のサンプルを変更して$(‘.open-5:not(:first)’).hide();で最初のメニュー以外を隠しています。
こうすることで最初のメニューだけを開いておくことができます。
また、:firstの部分を:nth-child(3n)とすることで空けておく場所を決めることもできます。

5.複数開くアコーディオンメニュー(閉じるボタンで閉じる)

See the Pen gOrGEdE by むぅ (@mugenweb) on CodePen.dark

JavaScript

$('.open-6').each(function(){
    $(this).css("height",$(this).height()+"px");
});
$('.open-6').hide();
$('.open-6').append('
<li class="img-close"><img src="batu.png" alt="閉じる"></li>

');
$('.btn-6').click(function () {
    $(this).next('.open-6').slideToggle('slow').siblings('.open-6').slideUp('slow');
    $(this).siblings('.btn-6').removeClass('active');
    $(this).toggleClass('active');
});
$('.img-close').click(function () {
    $(this).parent().slideToggle();
    $(this).parent().siblings('.btn-6').removeClass('active');
});

liの項目が長い場合、閉じるのにいちいち上のボタン部分まで戻って閉じるのが面倒な時に使える?サンプルです。
4のサンプルを変更して閉じるボタンを追加し、ボタンクリックで閉じることができます。
12、13行で今までは次の開閉要素を動かしましたが、.parent()とすることでimg-closeの親要素(ul)を隠すことができます。
ボタンの位置とかはjQueryで作ると面倒なのでcssでごまかして中央に配置してます。
使い道はスマホの方が多そうですけど、項目を細分化しろよってなると思うので使い道があるかどうかわかりませんw

6.多階層のアコーディオンメニュー

See the Pen NWrqzXp by むぅ (@mugenweb) on CodePen.dark

html

<div class="wrap">
  <h3 class="open_h3 btn-7">BRAND INFO</h3>
  <ul class="open_parent open-7"></ul>
  <h3 class="open_h3 btn-7">BRAND INFO</h3>
  <ul class="open_parent open-7"></ul>
  <h3 class="open_h3 btn-7">BRAND INFO</h3>
  <ul class="open_parent open-7"></ul>
</div>

JavaScript

var li_1 = "";
for (var i = 1; i <= 5; i++) {
  li_1 += "<li>項目" + i + "</li>";
}
var array = ["A", "B"];
$.each(array, function (index, val) {
  $('ul.open_parent').each(function () {
    $(this).append('<li><h3 class="open_h3 btn-7">' + val + '</h3></li>');
    $(this).children('li').append('<ul class="open_child open-7">' + li_1 + '</ul>');
  });
});

$('.open-7').hide();

$('.btn-7').click(function () {
  $(this).next('.open-7').slideToggle('slow');
  $(this).toggleClass('active');
});

jsでul.open_parentに子の開閉要素を追加しています。
また、親と同じ構造(h3の次に開閉するアコーディオンメニューの要素)とすることで、jsが短く書けるようになっています。

7.アンカーリンクをクリックすると、スクロールしアコーディオンメニュー開く

See the Pen
by むぅ (@mugenweb)
on CodePen.0

html

<ul>
  <li><a href="javascript:void(0)" class="anc" data-tag="pos1">1</a></li>
  <li><a href="javascript:void(0)" class="anc" data-tag="pos2">2</a></li>
  <li><a href="javascript:void(0)" class="anc" data-tag="pos3">3</a></li>
</ul>

<div class="wrap">
  <h3 class="open_h3 btn-7" id="pos1">BRAND INFO1</h3>
  <p class="info open-7"></p>
  <h3 class="open_h3 btn-7" id="pos2">BRAND INFO2</h3>
  <p class="info open-7"></p>
  <h3 class="open_h3 btn-7" id="pos3">BRAND INFO3</h3>
  <p class="info open-7"></p>
</div>

JavaScript

var text = '1917年に創業者のマリオ・プラダと兄弟によりインポートショップをオープン。世界中の素材や高品質な革を集め、イタリアの技術を投入したアイテムが有名に。1978年に孫娘のミウッチャ・プラダがオーナー兼デザイナーに就任。その後、マリオの使用していたナイロン地“ポコノ”に目を向け、レザーと併用したバッグが大ヒット。逆三角形のロゴプレートが一世を風靡したのは最近の記憶にも新しい。以来、PRADAはクリスマス時のシーズンアイテムや、上質なレザーを使用したSAFFIANOシリーズ等のブランドの代名詞と言われるアイテムを生み出した。近年では、映画への衣装提供・モバイル発売・車のデザイン等、服飾だけでなく様々な分野にも進出し、前進しつづけるブランド。';
$('.info').append(text);

$('.open-7').each(function(){
  $(this).css("height",$(this).height()+"px");
});
$('.open-7').hide();

$('.anc').click(function () {
  var tag = $(this).data('tag');
  if (!$('#'+tag).hasClass('active')){
    $('#'+tag).next('.open-7').slideToggle('slow');
    $('#'+tag).toggleClass('active');
  }
  
  var target = $('#'+tag);
  var position = target.offset().top;

  $('body,html').animate({scrollTop:position}, 400, 'swing');

  return false;
});

$('.btn-7').click(function () {
  $(this).next('.open-7').slideToggle('slow');
  $(this).toggleClass('active');
});

アンカーリンクをクリックすると、そのaタグのdata-tagを取得します。
開くアコーディオンメニューの状態を!$('#'+tag).hasClass('active')でチェックし、閉じた状態なら開く処理をします。
その後、該当位置までスクロールします。

これだけだと、アンカーリンクでしか開閉できない状態なので、今までのアコーディオンメニューの開閉も加えます。

javascript:void(0)については、下記を参照してください。

HTML5のaタグのrel=”noopener noreferrer”や、ページ内リンク、JavaScript実行を解説
HTML5のaタグのrel=”noopener noreferrer”や、ページ内リンク、JavaScript実行を解説しながら、様々なaタグの使い方をまとめました。 HTML5関連記事 ...

ナビゲーションメニュー関連記事

コメント

タイトルとURLをコピーしました