0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

アコーディオンパネル(子要素の高さを保持)をつくってみた

Last updated at Posted at 2019-02-24

##まえがき
コーディングを主で対応するようになって1年ほどの新米コーダーです。
自分なりの勉強や改善を備忘録として記録してます。
##実装
アコーディオンパネル実装

アコーディオンパネルの中の要素でlineHeightを使用したかったので、display: none;ではなく親要素をheight: 0;overflow: hidden;にして実装をしてます。
##ソースコード

HTML
<div class="js-accordion">
    <div class="accordionTrigger">ボタン1</div>
    <div class="accordionPanel">
        <div class="inner">
        	<a href="#">パネル1</a>
        </div>
    </div>
</div>
SCSS
.js-accordion {
	.accordionTrigger {
		//ボタンのスタイル
	}
	.accordionPanel {
		//パネルのスタイル
		height: 0;
		overflow: hidden;
		transition: .4s height;
		.inner {
			//パネル内のスタイル
		}
	}
}

非表示は.accordionPanelheight: 0;overflow: hidden;でおこないます。
overflow: hidden;ではみ出している部分も非表示にします。
.accordionPanelにmarginやpaddingの値を設定すると非表示時にその数値分余白が空いてしまうので、余白を空けるには子要素の.innerで設定をします。

親要素の高さを0にしても子要素の高さは0にならない特性を使用してます。
そのため、lineHeightなど高さが必要なjs(jQuery)が使えます。

jQuery
$(function(){
 var objAccordion = $('.js-accordion').children('.accordionTrigger');
    var FlagAccordionSingleDoor = 'js-accordion_singledoor';
    objAccordion.on('click',function(){
        var target_h = $(this).next().children().innerHeight() + 1;
        var panel = $(this).next();
        var parent = $(this).parent().parent();
        if(!parent.hasClass(FlagAccordionSingleDoor)) {
            if(panel.hasClass('show')) {
                if(!(panel.is(':animated'))){
                    $(this).removeClass('show');
                    panel.height(0).removeClass('show');
                }
            } else {
                if(!(panel.is(':animated'))){
                    $(this).addClass('show');
                    panel.height(target_h).addClass('show');
                }
            }
        } else {
            if(panel.hasClass('show')) { //片開き
                if(!(panel.is(':animated'))){
                    $(this).removeClass('show');
                    panel.height(0).removeClass('show');
                }
            } else {
                if(!(panel.is(':animated'))){
                    $(this).addClass('show').parent().siblings().find('.accordionTrigger').removeClass('show');
                    panel.height(target_h).addClass('show');
                    $(this).parent().siblings().find('.accordionPanel').height(0).removeClass('show');
                }
            }
        }
    });
});

js-accordion_singledoorを付けると開閉が連動するアコーディオンパネルになります。

var target_h = $(this).next().children().innerHeight() + 1;
子要素の高さを取得します。取得した高さに対して+1しているのは、ボーダー分の太さになります。ボーダーの太さが3pxで設定の場合は、+3に変更します。

if(!parent.hasClass(FlagAccordionSingleDoor)) {
js-accordion_singledoorをクラスとして持っているかで開閉連動のアコーディオンパネルか分岐をかけます。

if(!(panel.is(':animated'))){
アニメーション中はクリックしても動作しないようにアニメーションを監視してます。
##最後に
下層ページの共通部分として使用したかったため、今回作成をしました。
下層ページは自分以外のコーダーが入る予定で、各々記述をすると運用がやりずらくなるため開閉連動パターンも同じ記述にしてます。

ブラッシュアップしてもっと汎用的にしていきたいとおもいます!
##使用バージョン

<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?