アコーディオン系
エフェクトを
JSで極める
アコーディオンのように伸びたり縮んだりする効果を
JavascriptとCSSで実装する。

image: アコーディオン系エフェクトをJSで極める
Master of Accordion Effects

ボタンをクリックするとアコーディオンのようにビヨーンと
要素が伸びたり縮んだりするスクリプト

 | 2023/10/31

開発動機

毎回高さを指定するのは面倒なので、自動で高さを取得するスクリプトを開発
  • 俗にいうアコーディオン効果はCSSのアニメーションで実装可能

    通常はCSSでアコーディオンは実装できますが、高さをきっちり指定しないで“auto”などで設定するとアニメーションしてくれません。
    数が少なければ計算して固定値で設定するのもいいですが、案件によっては高さがインタラクティブに変化する場合や、数が多すぎる場合もあります。そういう場合は高さを自動で取得・計算できる方が効率がいいです。
    そこでJavascriptを使ってどのような場合でも、アコーディオン効果を付与する要素の高さを取得するスクリプトを開発しました。

考え方

シンプルに考える
  • 分かりやすい様に図にしてみました。

    表示BOXをクリックすると内包するコンテンツA,Bの高さを取得し、表示BOXの高さに追加する。
    transition: all 0.3s ease-out;が指定してあるので新しい高さまでアニメーションで拡大する。

    fig1-15fig2-12

開発
実装

HTML,CSS、JSのコーディングのポイント
  • ポイント部分のみを記載します。

    基本として各コンテンツ要素にはタイトルとコンテンツの二つで構成される。div.theme要素の数や、要素の中は好きなコーディングが可能。

    HTML

    <article class="block">
    		<h2 class="header">タイトル</h2>
    		<div class="theme"><!-- themeクラス要素がコンテンツの箱になる -->
    			<h3>サブタイトル</h3>
    			<p><a target="_sub" href="#">コンテンツA</a></p>
    			<p><a target="_sub" href="#">コンテンツB</a></p>
    			<p><a target="_sub" href="#"><span>コンテンツC</span></a></p>
    		</div>	
    		<div class="theme">
    			<h3>サブタイトル</h3>
    			<p><a target="_sub" href="#">コンテンツD</a></p>
    		</div>
    	</article>
  • CSS

    article.block{
    	margin-bottom: 12px;
    	height: 36px;/* 内包するタイトル要素の高さ */
    	overflow: hidden;
    	transition: all 0.3s ease-out;
    }
    
  • Java Script

    const i ={
    	wW:window.innerWidth,
    	wOW:window.outerWidth,
    	wTW: document.documentElement.clientWidth,
    	wH:window.innerHeight,
    	_items: '',
    	get items(){ 
    		return document.querySelectorAll( this._items );
    	},
    	set items(v){ 
    		this._items = v;
    	},	
    	_defH: document.querySelector('h2.header').getBoundingClientRect().height,
    	get defH(){return this._defH;},
    	set defH(v){this._defH = v;},
    	nonePassive: {passive : false},
    	passive: {passive : true}
    };
    
    i.items= 'h2.header';
    i.items.forEach(function(item){
    	item.addEventListener("click", expBlock, i.passive);
    });/* タイトル要素へボタンイベント設定 */
    
    function expBlock(e){/* 表示BOXが内包するコンテンツのすべての高さを取得合計し、表示BOXの高さへ追加する関数 */
    	const parentBox= e.currentTarget.closest('article');
    	if (parentBox.classList.contains('open')) {
    		parentBox.style.height= i.defH + 'px';
    		parentBox.classList.remove('open');
    	}else{
    		i.items= 'article';
    		i.items.forEach(function(item){
    			item.style.height= i.defH + 'px';
    			item.classList.remove('open');
    		});
    		parentBox.classList.add('open');
    		let boxesH= 0;
    		const themBoxes= parentBox.querySelectorAll('.theme');/* themeクラスを全て配列へ格納 */
    		let count= 0;
    		themBoxes.forEach(function(item){
    			count++;
    			boxesH += parseInt(item.getBoundingClientRect().height);
    		});
    		const boxH=boxesH + i.defH ;
    		parentBox.style.height= boxH + 'px';
    	}
    }
  • 参考コード

    参考:https://labo.studio-happyvalley.com/accordion/

『アコーディオン系エフェクトをJSで極める』関連のお薦め

このページで紹介しているプログラムやビジュアルなどご依頼いただければ実装を賜ります。
お問い合わせはこちら