LoginSignup
5
1

More than 3 years have passed since last update.

高さが可変のアニメーションするアコーディオンメニュー 【JavaScript】【高さ可変】【脱jQuery】

Last updated at Posted at 2020-02-19

アコーディオンメニューはサイトの様々な箇所で使われるため、ページの中で複数箇所に設置でき、CSSで容易に装飾を変更できるものを作りました。
特に、アコーディオンのコンテンツの高さをcssで都度指定の必要がないことも使い回しのポイントです。

動作デモ

See the Pen アコーディオンメニュー by masato yamada (@marchin133) on CodePen.

使い方

JavaScriptを読み込み、cssに追記します。

JavaScript

別ファイルなどにして読み込んでください

acordion.js
document.addEventListener('DOMContentLoaded', function () {

    var acodionMenu = document.querySelectorAll('.acdn');
    var acodionContentHight = [];

    for (var i = 0; i < acodionMenu.length; i++) {

        acodionContentHight[i] = acodionMenu[i].nextElementSibling.clientHeight + "px";
        acodionMenu[i].nextElementSibling.style.height = acodionContentHight[i];

            if (acodionMenu[i].nextElementSibling.classList.contains('acdn_close')) {
                acodionMenu[i].nextElementSibling.style.height = '0px';
            }

        acodionMenu[i].addEventListener('click', function () {

            var clickitem = Array.prototype.indexOf.call(acodionMenu, this);

            if (this.nextElementSibling.classList.contains('acdn_close')) {
                this.nextElementSibling.style.height = acodionContentHight[clickitem];
            } else {
                this.nextElementSibling.style.height = '0px';
            }

            this.classList.toggle('acdn_open');
            this.classList.toggle('acdn_close');
            this.nextElementSibling.classList.toggle('acdn_open');
            this.nextElementSibling.classList.toggle('acdn_close');

        }, false);

    }


}, false);

html

1)アコーディオンの開閉に使う要素に、.acdn クラスをつけてください。
2)ページが表示されたときに閉じているときは.acdn_close も付与してください。逆に展開しているときは.acdn_openをつけてください。
3).acdnが付けられた要素のの要素がアコーディオンとして機能します。その要素に展開状態を示す.acdn_closeまたは.acdn_openを付与してください。
4)htmlはこれだけです。

sample.html
<div class="menu_title acdn acdn_close">アコーディオンメニュー1</div> <!-- 閉じた状態で表示させたい場合 -->
    <div class="menu_content acdn_close">
        <ul>
            <li>項目1</li>
            <li>項目2</li>
            <li>項目3</li>
            <li>項目4</li>
        </ul>
    </div>
    <div class="menu_title acdn acdn_open">アコーディオンメニュー2</div> <!-- 開いた状態で表示させたい場合 -->
    <div class="menu_content acdn_open">
        <ul>
            <li>項目1</li>
            <li>項目2</li>
            <li>項目3</li>
            <li>項目4</li>
        </ul>
    </div>
    <div class="menu_title acdn acdn_open">アコーディオンメニュー2</div>
    <div class="menu_content acdn_open">
        <ul>
            <li>項目1</li>
            <li>項目2</li>
            <li>項目3</li>
            <li>項目4</li>
        </ul>
    </div>

CSS

1).menu_title クラス名不問 アコーディオンの開閉として使用する要素です。自由に装飾してください。jsでクリックイベントが付きますので、面積があったほうがいいです。
2).menu_content クラス名不問 アコーディオンで高さを、もともとの高さ→0pxになる要素です。必要に応じて装飾ください。

overflow: hidden; この内側の要素を消す(見えなくする)ために必要です。
transition: all 0.5s ease-out; トランジションはお好きな数値に変更などしてください。設定しないとアニメーションしません。

3)要素に.acdn_closeまたは.acdn_openが付与されることを利用して、展開時や縮小時に表現を変えることができます。
例:サンプルでは押された要素(.menu_title)の背景色を変えています。

sample.css
.menu_title{
  width:400px;
  height: 50px;
}

.menu_content{
  width:400px;
  overflow: hidden;
  transition: all 0.5s ease-out;
}

.menu_title.acdn_open{
  background-color: #cccccc;
}

動作のしくみ

.acdnが付けらた要素にクリックイベントを付け、その次の要素の高さを取得しています。
一度高さを格納したあとに、.acdn_closeがついている要素については高さを0pxに設定して閉じた状態にしています。
高さが画面描画後に動的に変更されない限り、アコーディオンコンテンツの中身の高さを調べてcssに記述することなく、トランジションさせることができます。

クリックイベントが起きるたび、要素に.acdn_closeまたは.acdn_openを都度付けたり消したりすることで動きを実現しています。

コードが冗長であるなど、ご指摘いただけると嬉しいです。

5
1
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
5
1