アコーディオン内のメニュークリック後、アコーディオンを閉じページ内リンク先に移動する

##はじめに
こんにちは、フロントエンドエンジニア歴1年目で日々勉強中のズミです。
実はQiita初投稿・・ドキドキです。

記念すべき初投稿では、アコーディオン内のメニューをクリックしたあとに、アコーディオンが閉じてページ内リンク先に移動する動きの実装をご紹介します。
案件で実装するにあたり苦労したのですが、意外と短いコードで解決できました。
それでは、いきましょう！


##やりたいこと
アコーディオンメニューのリンク先がページ内にある場合に、
①アコーディオン内のメニューをクリック
②アコーディオンを閉じながらリンク先に遷移

CodePenで実装した完成形は下記なので、イメージしながらこの先をお読みいただければと思います。

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="html,result" data-user="suzuy" data-slug-hash="ZEppeBE" 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="アコーディオン内メニュークリック時の動作">
  <span>See the Pen <a href="https://codepen.io/suzuy/pen/ZEppeBE">
  アコーディオン内メニュークリック時の動作</a> by Suzu (<a href="https://codepen.io/suzuy">@suzuy</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>


##まずはslideToggleでアコーディオンメニューを実装

jQueryのslideToggleを使い、ベースのアコーディオンメニューをつくります。

```html:html
<div class="menu-box">
  <button type="button" id="btn-accordion" class="menu_btn">メニューボタン（クリックして開閉）</button>
  <ul class="menu_list">
    <li><a href="#menu_01">メニュー１</a></li>
    <li><a href="#menu_02">メニュー2</a></li>
    <li><a href="#menu_03">メニュー3</a></li>
  </ul>
</div>
```

```scss:scss
.menu-box {
  position: fixed;
  top: 10px;
  left: 10px;  
}

.menu_btn {
  padding: 10px;
  cursor: pointer; 
  background-color: #5a6173;
  color: #fff;
}

.menu_list {
  display: none; // アコーディオンの中身は、あらかじめ非表示にしておきます。
  margin: 0;
  padding-inline-start: 0px;
  list-style: none;
  background-color: #f2f2f2;
  li {
    padding: 5px 0 5px 10px;
    border-bottom: solid 1px #fff;
    a {
      display: block;
      text-decoration: none;
      color: #000;
    }
  }
}
```

```js:js
$(function() {
  $('#btn-accordion').on('click', function() {
    $(this).next().slideToggle();
  });
});
```


##ページ内リンク先に飛ぶアコーディオンメニューを実装

ページ内リンク先メニュー1〜メニュー3のsectionを用意します。
また、それぞれのsectionにスムーススクロールで遷移したいので、スムーススクロールの記述をjsに入れます。


```html:html
<div class="menu-box">
  <button type="button" id="btn-accordion" class="menu_btn">メニューボタン（クリックして開閉）</button>
  <ul class="menu_list">
    <li><a href="#menu_01">メニュー１</a></li>
    <li><a href="#menu_02">メニュー2</a></li>
    <li><a href="#menu_03">メニュー3</a></li>
  </ul>
</div>

<section class="sec_01">
  <h1 id="menu_01" class="title_01">メニュー1</h1>
  <p>メニュー１です。</p>
</section>

<section class="sec_02">
  <h1 id="menu_02" class="title_02">メニュー2</h1>
  <p>メニュー2です。</p>
</section>

<section class="sec_03">
  <h1 id="menu_03" class="title_03">メニュー3</h1>
  <p>メニュー3です。</p>
</section>
```

```scss:scss
.menu-box {
  position: fixed;
  top: 10px;
  left: 10px;  
}

.menu_btn {
  padding: 10px;
  cursor: pointer; 
  background-color: #5a6173;
  color: #fff;
}

.menu_list {
  display: none; // アコーディオンの中身は、あらかじめ非表示にしておきます。
  margin: 0;
  padding-inline-start: 0px;
  list-style: none;
  background-color: #f2f2f2;
  li {
    padding: 5px 0 5px 10px;
    border-bottom: solid 1px #fff;
    a {
      display: block;
      text-decoration: none;
      color: #000;
    }
  }
}

section {
  height: 1000px; 
  &.sec_01 {
    margin-top: 60px;
  }
  h1 {
    margin-top: -60px;
    padding-top: 60px;
  }
}
```

```js:js
// スムーズスクロール
$(function() {
  $('a[href^="#"]').on('click', function() {
    const speed = 400;
    const href= $(this).attr('href');
    const target = $(href === '#' || href === '' ? 'html' : href);
    const position = target.offset().top;
    $('body,html').animate({scrollTop:position}, speed, 'swing');
    return false;
  });
});

// アコーディオン
$(function() {
  $('#btn-accordion').on('click', function() {
    $(this).next().slideToggle();
  });
});
```


しかし、このままでは、アコーディオン内のメニューをクリックしリンク先に遷移後も、メニューは開いたままになってしまいます。
これを解決するために、jsで下記のコードを追加します。

##
```js:js
// スクロール
// 省略

// アコーディオン
$(function() {
  // 省略
  $('.menu_list li a').on('click', function() {
    $('.menu_list').slideUp();
  });
});
```


アコーディオン内のメニューをクリックしたら、slideToggleでアコーディオンの中身を非表示にする、という実装です。
たった3行で解決・・この実装を考えるまでに結構時間かかっちゃいました。


##最後に
しくみがわかるととてもシンプルな実装でしたが、案件で実装した当初は結構時間かけて調べて解決しました。
jsやjQueryでの実装がまだまだ弱いので、2021年はjsをある程度使いこなせるようになりたい・・いや、なる！！

最後までお読みいただきありがとうございました\（^^）/


##参考にさせていただいたリンク
* https://liginc.co.jp/web/js/jquery/34048
* https://webkcampus.com/201907/1684/