jQueryで実現!カスタマイズ可能なハンバーガーメニューの実装(コピペで実現可能)
前回のjQuery解説編に続いて、今回はjQueryを使って実際の実装について語っていきたいと思います。オトナ帝国のサイトではいくつかjQueryを動かしていますが、今回はハンバーガメニューについてご紹介します。
今日の内容はフロントエンドエンジニア初学者向けです
エンジニアでないと面白くないかもです・・(笑)
ハンバーガーメニューとは
ハンバーガメニューとはその名の通りハンバーガーです。Wikipediaによるとハンバーガー (hamburger) とは、牛肉のパティをバンズと呼ばれるパンに挟んだ食べ物。と呼ばれているようです。オトナ帝国では下記の見た目になっています。
もちろん、サイト内にハンバーガーがあるわけではないのですが、右上の白矢印3重線、その見た目からハンバーガー、そして開くとメニューが出てくる、ゆえにハンバーガメニューと呼ばれております。
ハンバーガメニューの実装方法について
まずは参考までにフォルダ構造(すべて同一フォルダ内)の写真も張っておきます。
ハンバーガメニューの実装ですが、登場人物は3人です。①メニューボタン②表示されるメニュー③メニューの中のリンクです。
実際のデモページはこちらから確認できます。ちなみにソースは本当に最低限。あえて、jsから記載していますが、jsでの登場人物①~③は下記に格納されています。
①メニューボタン:4行目の$targetBtn
②表示されるメニュー:5行目の$jtargetMenu
③メニュー内のリンク:6行目の$targetLink
jsの中身について
//jsファイル
$(function () {
(function () {
const $targetBtn = $(".js-menu-btn");
const $targetMenu = $(".js-nav-menu");
const $targetLink = $(".js-nav-link");
$targetBtn.on("click touchend", function () {
$(this).toggleClass("active");
// menu open close
if ($targetBtn.hasClass("active")) {
$targetMenu.addClass("active");
return false;
} else {
$targetMenu.removeClass("active");
return false;
}
});
})();
});
やっていることはシンプル、$targetBtnがクリックされたら$jtargetMenuにactiveというclassを付与、activeのclassがあるときは$targetBtnクリック時にはactive除去、つまりactiveがあるときとない時でcss制御で見た目をカスタマイズしているだけです!
htmlの中身について
このjs動かすためのhtmlですね。最低限のclassだけ付与しておりますが、基本的には、js-から始まるのがjs関連で使うもの、あとは基本的デザインのためのclassです。<head>の最後と</body>直前のcssとjsのリンク先はご自由にどうぞ。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<title>ハンバーガーテスト</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta http-equiv="content-language" content="ja" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<link rel="stylesheet" href="./hoge.css" />
</head>
<body>
<div class="container">
<div class="contents">
<div class="menu">
<button class="menu__btn js-menu-btn" type="button">
<span class="menu__label">開閉</span>
<span class="menu__bar menu__bar--1"></span>
<span class="menu__bar menu__bar--2"></span>
<span class="menu__bar menu__bar--3"></span>
</button>
</div>
<div class="menuContent js-nav-menu">
<div class="menuNav">
<ul class="menuNav__list">
<li class="menuNav__item"><a class="menuNav__link js-nav-link" href="/">top</a></li>
<li class="menuNav__item"><a class="menuNav__link js-nav-link" href="/">記事へ</a></li>
<li class="menuNav__item"><a class="menuNav__link js-nav-link" href="/">google</a></li>
</ul>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="./hoge.js"></script>
</body>
</html>
少し癖があるとすると、3重線ボタンを表現するため空のspanを3つ並べています。あとは元々がbemなので、少しclass名が長いです・・(笑)
cssの中身について
//cssファイル
@charset "UTF-8";
body {
margin: 0;
}
.contents {
position: relative;
background-color: #000;
height: 55px;
}
.menu {
position: absolute;
top: 10px;
right: 10px;
display: block;
z-index: 10;
}
.menu__btn {
display: block;
position: relative;
border: 0 none;
padding: 0;
margin: 0;
background-color: transparent;
width: 42px;
padding: 8px;
height: 34px;
outline: none;
overflow: hidden;
}
.menu__label {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}
.menu__bar {
display: block;
width: 28px;
height: 2px;
z-index: 3;
background-color: #fff;
position: absolute;
left: 50%;
transition-property: all;
transition-duration: 0.5s;
transition-delay: 0s;
transition-timing-function: cubic-bezier(0.19, 1, 0.22, 1);
}
.menu__bar--1 {
top: 8px;
transform: translate(-50%, 0);
}
.active .menu__bar--1 {
top: 50%;
transform: translate(-50%, -50%) rotate(-45deg);
}
.menu__bar--2 {
top: 50%;
transform: translate(-50%, -50%);
opacity: 1;
}
.active .menu__bar--2 {
transform: translate(100%, -50%);
opacity: 0;
}
.menu__bar--3 {
bottom: 8px;
transform: translate(-50%, 0);
}
.active .menu__bar--3 {
top: 50%;
bottom: 0;
transform: translate(-50%, -50%) rotate(45deg);
}
.menuContent {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
background-color: #000;
transform: translate(100%, 0);
transition-property: all;
transition-duration: 0.5s;
transition-delay: 0s;
transition-timing-function: cubic-bezier(0.19, 1, 0.22, 1);
z-index: 2;
}
.menuContent.active {
transform: translate(0, 0);
}
.menuNav {
height: 100%;
}
.menuNav__list {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100%;
padding: 0 0 30px;
}
.menuNav__item {
margin: 6px 0;
}
.menuNav__link {
color: #fff;
font-size: 18px;
text-decoration: none;
display: block;
}
scssで書いてコンパイル後のcssをそのまま持ってきているので、少し見にくいかもですが、activeの記載があるところで動かしています。
ハンバーガメニューについて
正直デザインは好みもあるので、好きなデザインをいろいろとってきてもらえればいいのかなと思いますが、基本的にjsではclassの管理、css側で見た目を調整することでカスタマイズの自由度をある程度持たせております。
皆さんが実際に組まれるときに、何かの参考になれば幸いです。
最後に
いかがでしたでしょうか。今回はがっつりjsの内容で少し難しかったかもしれません。どちらかというと、初級学者向けの内容なので・・・フロントエンドになじみがない方だと・・・あれな内容かもです、、ごめんなさい
ただなじみがある方からすると、ハンバーガメニューは意外と永遠のテーマですよね。
次回はまた少し抽象的な内容にできれば、と思っております。それでは~
ゲームし放題の施設「オトナ帝国」の2拠点目となる浅草橋基地を作るにあたり、クラウドファンディングを実施しています!支援していただけると「懐かしさに浸れる秘密基地」をいち早く体験して頂けます。限定数のあるメニューもあるのでご興味ある方はお早めに!