##はじめに
こんにちは、フロントエンドエンジニア歴1年目で日々勉強中のズミです。
実はQiita初投稿・・ドキドキです。
記念すべき初投稿では、アコーディオン内のメニューをクリックしたあとに、アコーディオンが閉じてページ内リンク先に移動する動きの実装をご紹介します。
案件で実装するにあたり苦労したのですが、意外と短いコードで解決できました。
それでは、いきましょう!
##やりたいこと
アコーディオンメニューのリンク先がページ内にある場合に、
①アコーディオン内のメニューをクリック
②アコーディオンを閉じながらリンク先に遷移
CodePenで実装した完成形は下記なので、イメージしながらこの先をお読みいただければと思います。
See the Pen アコーディオン内メニュークリック時の動作 by Suzu (@suzuy) on CodePen.
##まずはslideToggleでアコーディオンメニューを実装
jQueryのslideToggleを使い、ベースのアコーディオンメニューをつくります。
<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>
.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;
}
}
}
$(function() {
$('#btn-accordion').on('click', function() {
$(this).next().slideToggle();
});
});
##ページ内リンク先に飛ぶアコーディオンメニューを実装
ページ内リンク先メニュー1〜メニュー3のsectionを用意します。
また、それぞれのsectionにスムーススクロールで遷移したいので、スムーススクロールの記述をjsに入れます。
<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>
.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;
}
}
// スムーズスクロール
$(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で下記のコードを追加します。
// スクロール
// 省略
// アコーディオン
$(function() {
// 省略
$('.menu_list li a').on('click', function() {
$('.menu_list').slideUp();
});
});
アコーディオン内のメニューをクリックしたら、slideToggleでアコーディオンの中身を非表示にする、という実装です。
たった3行で解決・・この実装を考えるまでに結構時間かかっちゃいました。
##最後に
しくみがわかるととてもシンプルな実装でしたが、案件で実装した当初は結構時間かけて調べて解決しました。
jsやjQueryでの実装がまだまだ弱いので、2021年はjsをある程度使いこなせるようになりたい・・いや、なる!!
最後までお読みいただきありがとうございました\(^^)/
##参考にさせていただいたリンク