5
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 3 years have passed since last update.

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

Last updated at Posted at 2020-12-09

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

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

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

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

See the Pen アコーディオン内メニュークリック時の動作 by Suzu (@suzuy) on CodePen.

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

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

html
<div class="menu-box">
  <button type="button" id="btn-accordion" class="menu_btn">メニューボタン(クリックして開閉)</button>
  <ul class="menu_list">
    <li><a href="#menu_01">メニュー1</a></li>
    <li><a href="#menu_02">メニュー2</a></li>
    <li><a href="#menu_03">メニュー3</a></li>
  </ul>
</div>
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
$(function() {
  $('#btn-accordion').on('click', function() {
    $(this).next().slideToggle();
  });
});

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

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

html
<div class="menu-box">
  <button type="button" id="btn-accordion" class="menu_btn">メニューボタン(クリックして開閉)</button>
  <ul class="menu_list">
    <li><a href="#menu_01">メニュー1</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>メニュー1です。</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
.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
// スムーズスクロール
$(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
// スクロール
// 省略

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

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

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

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

##参考にさせていただいたリンク

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