めっちゃ汎用的なアコーディオンメニューを作ろう

[JavaScript 2 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/javascript2) の18日目の記事です。

#使うもの
HTML,CSS(SCSS),jQuery

#目的
・どんなデザインでも使える
・既にあるコードにも適用が容易
そんな汎用的なアコーディオンメニューを作る

どちらかといえばCSS寄りの内容かも…?(カレンダー新設する勇気が無かったのでjsにお邪魔しています…:relaxed:)
#概要
:fist::fist::fist:とにかく装飾と分離する！！:fist::fist::fist:
汎用的に作るにはこれが重要です

装飾は装飾、機能は機能でクラスをわけましょう

```html
<!-- HTML -->
<div class="js_acc_trigger acc_trigger">
</div>
<div class="js_acc_content acc_content">
</div>
```
上記のように、今回用意するクラスは4つだけ
(状態を表すためにjsで付与する.is_openも含めると5つ)

1. jsでアコーディオンの開閉状態を操作する用の2つのクラス
`.js_acc_trigger`←イベントのトリガーにつける　ボタン的な役割
`.js_acc_content`←このクラスがついた要素の中にアコーディオンの中身を入れる

2. CSSでアコーディオンが開いたり閉じたりする見た目を記述する用の2つのクラス
`.acc_trigger`
`.acc_content`

```javascript
//jQuery
//アコーディオンメニュー
var accordionFix = function(evt){
    evt.stopPropagation();

    if($(this).hasClass('is_open')){
        $(this).next('.js_acc_content').removeClass('is_open');
        $(this).removeClass('is_open');
    }
    else{
        $(this).next('.js_acc_content').addClass('is_open');
        $(this).addClass('is_open');
    }
}

$('.js_acc_trigger').on('click', accordionFix);
```
「.js_acc_trigger」に「.is_open」クラスがついていたら、外す＆
「.js_acc_trigger」の直後の「.js_acc_content」からも「.is_open」を外す

「.js_acc_trigger」に「.is_open」クラスがついていなかったら、つける＆
「.js_acc_trigger」の直後の「.js_acc_content」にも「.is_open」をつける

現実世界のスイッチ的な感じで、押す度にONとOFFを切り替えます。

```scss

//SCSS

.acc_trigger {
    &.is_open {
        //+-アイコン
        .fa-plus-circle::before {
            content: '\f056';
        }
        //矢印アイコン
        .fa-chevron-down::before {
            content: '\f077';
        }
    }
}
.acc_content {
    display: none;

    &.is_open {
        display: block;
    }
}
```
↑CSSはこんな感じで、基本的に表示か非表示のみ。装飾用のスタイルを含めないようにします。
.acc_contentにborderをつけたい、とかアイコンのサイズを変更したい、といった場合は装飾用のクラスを作ってそちらで対応します。


#どう使い勝手が良いのか
たとえば既存コードでなんか色々クラスがあって装飾されていても…
<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="html,result" data-user="xyuno0717" data-slug-hash="VwYmXLB" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="acc1">
  <span>See the Pen <a href="https://codepen.io/xyuno0717/pen/VwYmXLB">
  acc1</a> by xyuno0717 (<a href="https://codepen.io/xyuno0717">@xyuno0717</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

↓こんな感じで、divで囲んで4つのクラスをつけ足すだけで、既存のHTMLが簡単にアコーディオンになります。
<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="html,result" data-user="xyuno0717" data-slug-hash="qBEqobo" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="acc2">
  <span>See the Pen <a href="https://codepen.io/xyuno0717/pen/qBEqobo">
  acc2</a> by xyuno0717 (<a href="https://codepen.io/xyuno0717">@xyuno0717</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
押せることがわかりやすいようにアイコンもつけて、「.is_open」クラスによって「+-」を切り替えたりすると見た目もわかりやすくて良い感じになります

#終わり
こういう汎用的なものをどんどん作って作業を効率化していきたいですね！

イベントに釣られてQiita初投稿しました。
メルカリさん・メルペイさん、クリスマスプレゼントが欲しいです！！！よろしくおねがいします！