自分用の備忘録に作りました。
pureなJSでアコーディオンメニューを実装し、一応簡単な形ですがレスポンシブ対応してるので、参考にしてください。
完成図
コード
※注意点としては、コードはPCファーストになってます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>navber</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Font Awesome -->
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.1/css/all.css" integrity="sha384-vp86vTRFVJgpjF9jiIGPEEqYqlDwgyBgEF109VFjmqGmIY/Y4HV4d3Gp2irVfcrp" crossorigin="anonymous">
<!-- Google Font -->
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;700&display=swap" rel="stylesheet">
<!-- CSS -->
<link rel="stylesheet" href="./css/style.css">
<!-- JS -->
<script src="./js/main.js"></script>
</head>
<body>
<!-- header -->
<header>
<h1>NavberTest</h1>
<p>~ navber test web app ~</p>
</header>
<!-- navigation for pc -->
<nav class="pc-nav">
<ul>
<li><a href="#">menu1</a></li>
<li><a href="#">menu2</a></li>
<li><a href="#">menu3</a></li>
</ul>
</nav>
<!-- navigation for sp -->
<nav class="sp-nav">
<ul>
<li><a href="#">menu1</a></li>
<li><a href="#">menu2</a></li>
<li><a href="#">menu3</a></li>
</ul>
</nav>
<!-- bars icon -->
<div class="bars" id="spNavToggle"><i class="fas fa-bars"></i></div>
</body>
</html>
@charset "UTF-8";
/* reset */
*{
margin: 0;
padding: 0;
font-family: 'Noto Sans JP', sans-serif;
line-height: 1;
}
ul{
list-style: none;
}
a{
text-decoration: none;
}
/* header */
header{
background: #000000;
color: #ffffff;
padding: 10px;
margin-bottom: 20px;
}
/* navigation for pc */
nav.pc-nav{
max-width: 960px;
margin: 0 auto;
}
nav.pc-nav ul{
display: flex;
}
nav.pc-nav li{
width: 100%;
border-right: 1px solid #ffffff;
}
nav a{
display: block;
line-height: 44px;
text-align: center;
width: 100%;
background: #000000;
color: #ffffff;
}
/* navigation for sp */
nav.sp-nav{
/* 768px以上では非表示にする。 */
display: none;
}
nav.sp-nav li{
border-top: 1px solid #ffffff;
transition: 0.3s;
/* デフォルトでは高さを0。そして0からはみ出た分を非表示にする。 */
height: 0;
overflow: hidden;
}
nav.sp-nav li.active{
/* JSで表示させるときのCSS。overflowを初期値のvisibleに書き換える。 */
height: 44px;
overflow: visible;
}
/* bars icon */
.bars{
/* 768px以上では非表示にする。 */
display: none;
width: 50px;
height: 50px;
border: 2px solid #ffffff;
border-radius: 5px;
color: #ffffff;
text-align: center;
font-size: 35px;
/* positionでbodyの右上に配置*/
position: absolute;
top: 10px;
right: 10px;
}
.bars i{
/* アイコンを縦の真ん中に配置 */
line-height: 50px;
}
/* under 767px size */
@media screen and (max-width: 767px){
header{
margin: 0;
}
/* ipad以下ではpc版のnavを非表示。sp版のnavとbarsボタンを表示させる。 */
nav.pc-nav{
display: none;
}
nav.sp-nav{
display: block;
}
.bars{
display: block;
}
}
window.onload = function(){
// 変数宣言
const spNavToggle = document.getElementById('spNavToggle');
const spNavLi = document.querySelector('.sp-nav').querySelectorAll('li'); //.sp-nav内のliを全て取得し、配列化。
// クリックイベント
spNavToggle.onclick = function(){
// 配列をアイテム1つずつ処理。liにactiveクラスを付与している。
spNavLi.forEach((liTag) => {
liTag.classList.toggle('active');
})
}
}
ポイント
html
・PC版とSP版でnavを2つ書いてます。
→この方がコード量は多少増えますが、メンテが楽です。
css
・上記理由でnavが2つあるので、出来るだけ共通のプロパティはまとめ、それ以外はnav.pc-nav
,nav.sp-nav
と使い分けてCSSを適用しています。
・アコーディオンメニューの肝であるnav.sp-nav li
のheight: 0;
,overflow: hidden;
→これがメインの部分です。初期値は非表示にしたいのですが、display:none;
ではなく、アコーディオンメニューの演出の都合上、上記のような書き方になっています。その後ここにactive
クラスが追加されることでheight: 44px;
,overflow: visible;
が適用され、アコーディオンのように徐々に膨らむような動きになります。
JS
ここは特に、難しいことは無いのですが、forEach
で繰り返し処理をしたいので、配列として扱えるquerySelector
を使っています。
最後に
改めてpureなJSってコード書くのめんどいなって思いました。でもプログラミングしてるなって感覚になって出来ると楽しいですねw
今後もこう言った小ネタ的なものをガンガン上げていきたいと思います。お疲れ様でした。