はじめに
こんにちは.マエカワです.
今回はハンバーガーメニューのサンプルコードを読み進めながら,自分でコーディングしていくという個人的な勉強回です.「bootstrapでええやん」と思われるかもしれないですが,カッコいいことは自力で実装できるようにしたいのです.
この記事で参考にするのは,
lab.sonicmoov.com
で紹介されている「ハンバーガーメニューhamburger slide accordion menu」という章で公開されているコードです.今回書いていくコードで,ほとんど同じものが出来上がると思います.
正直言って,どこのサイトでも説明されていることなので自分用のメモとして保存しておこうかと思います.
前提
今回の記事は,自分と同じレベルの方々向けのものになっています.「HTML,CSS,JavaScriptはちょっとだけ触ったことあるけど,それらの連携はあんましたことないなぁ」という超絶初心者向けの記事になっています.その点,よろしくお願いいたします.
本実装
フォルダ構造
今回想定するフォルダ構造は以下の通りです.
作業フォルダ
┣ css
┃┗ samplePage_01.css
┣ js
┃┗ samplePage_01.js
┗ samplePage_01,html
HTML
ハンバーガーメニューの本質は,3つの細長いspanオブジェクトです.これらが回転したり動いたりすることでカッコよく見えるわけです.コードは以下の通り.
<html>
<head>
<title>SAMPLE PAGE | 01</title>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<link rel="stylesheet" href="./css/samplePage_01.css">
<script src="./js/samplePage_01.js"></script>
</head>
<body>
<div id="menu">
<div class="hamberger">
<span></span>
<span></span>
<span></span>
</div>
<ul class="menu-list">
<li class="menu-contents">Content 01</li>
<ul class="menu-subcontents">
<li><a href="#">sub-Content 01</a></li>
<li><a href="#">sub-Content 02</a></li>
<li><a href="#">sub-Content 03</a></li>
</ul>
<li class="menu-contents">Content 02</li>
<ul class="menu-subcontents">
<li><a href="#">sub-Content 01</a></li>
<li><a href="#">sub-Content 02</a></li>
</ul>
</ul>
</div>
</body>
</html>
ひとつ注意ですが,jQueryのインポートは一番最初にしてしまいましょう.そうしないと,「$なんていう記述方法に適応していません」みたいな感じのエラーが出てしまいます.ここだけ注意.というか,自分がこのエラーに引っかかって時間を無駄にしてしまった....あとは,spanを3個とメニューにしたいリストを記述するだけです.
CSSのコードは以下の通りです.ところどころHTMLで定義していないクラス名(具体的にはopenクラス)に関する記述があると思いますが,この部分がJSと連携させる部分になります.あとで書きますが,jQueryを使うと特定のイベント発生時にクラスを追加することができます.そのため,追加されたクラスに関する装飾をCSSであらかじめ記述しておくことによって,見た目の良い「なんかすげぇ」という動きを実現できるというわけです.
.hamberger {
cursor: pointer;
left: 0px;
width: 30px;
height: 30px;
margin: 2px;
}
.hamberger span {
left: 0px;
width: 100%;
height: 4px;
position: relative;
display: block;
background-color: black;
border-radius: 2px;
transform: rotate(0deg);
transition: .4s ease-in-out;
}
.hamberger span:nth-child(1) {
top: 0px;
}
.hamberger span:nth-child(2) {
top: 8px;
}
.hamberger span:nth-child(3) {
top: 16px;
}
.hamberger.open span:nth-child(1) {
transform: translateY(12px) rotate(135deg);
}
.hamberger.open span:nth-child(2) {
transform: translateX(-150%);
}
.hamberger.open span:nth-child(3) {
transform: translateY(-12px) rotate(-135deg);
}
ul {
list-style: none;
}
.menu-list {
cursor: pointer;
position: absolute;
left: -100%;
width: 300px;
height: auto;
padding: 0%;
}
.menu-contents, .menu-subcontents {
position: relative;
width: 100%;
height: 40px;
left: 10px;
padding: 10px;
}
.menu-contents {
border-top: 2px solid coral;
background-color: rgb(255, 105, 19);
color: white;
}
.menu-subcontents {
display: none;
background-color: rgb(73, 73, 73);
}
.menu-subcontents a {
color: white;
text-decoration: none;
}
ちょっと変わっているところは以下の通り.
- 33~43行目:openクラスが適用されたときの装飾
- ここで,後述するJavaScriptでopenクラスが追加されたときの装飾を記述しています.
- hambergerクラスにはtransition属性で,数値で表される属性(今回はtransform rotate属性)の変化を0.4秒でアニメーションのように適用しています.そのため,open属性が追加されたときにspanオブジェクトがクルクル回るようになります.
- このtransition属性でアニメーションのように表現されるのは「数値で表される属性の変化のみ」であるところに注意しましょう.例えば,RGB値とかwidthとかheightとか.
お次はJSです.JSでは,ハンバーガーとメニューがクリックされたときの処理を書いています.簡単に説明すると,以下の2つの処理をしています.
- hambergerクラスを持つ要素がクリックされたらmenu-listクラスに関してopenクラスを切り替えて(なかったら足して,あったら取って),openクラスがある場合はmenu-listクラスにactiveクラスを追加し,leftを0.4秒かけて0%にする(画面ににゅるっと出てくるようにする).
- ここでhambergerクラスに追加したopenクラスによって,CSSで記述したアニメーションが適用されます.
- menu-contentsクラスを持つ要素がクリックされたら,クリックされた要素の次の(つまりsub-contentsクラスを持つ)要素をスライドさせて表示し,それ以外のsub-contentsクラスを持つ要素はスライドで非表示にする.
これだけ.字面にするとややこしそうですが,コードにするととても分かりやすいと思います.それでは見ていきましょう.
$(function(){
function slideMenu() {
let activeState = $(".menu-list").hasClass("active");
$(".menu-list").animate({left: activeState ? "0%" : "-100%"}, 400);
}
$(".hamberger").click(function(event){
event.stopPropagation();
$(".hamberger").toggleClass("open");
$(".menu-list").toggleClass("active");
slideMenu();
});
$(".menu-list").find(".menu-contents").click(function(event){
event.stopPropagation();
$(this).next().slideToggle("fast");
$(".menu-subcontents").not($(this).next()).slideUp("fast");
});
});
このコードの簡単な説明は以下の通りです.本当に,目立ったことは何一つしていません.
- 2行目:slideMenuメソッド
- ここではmenu-listクラスを持つ要素にactiveクラスもくっついているときに,menu-listクラスのleft属性を0.4秒で0%にします.もしactiveクラスがついていなかった場合は-100%にします.
- 7行目:ハンバーガーがクリックされたときの処理
- hambergerクラスにopenクラスをトグル
- menu-listクラスにactiveクラスをトグル
- slideMenuメソッドの実行
- 14行目:menu-listクラス内のmenu-contentsクラスがクリックされたときの処理
- menu-listクラスの次のクラス(つまりmenu-subcontentsクラス)をスライドさせて表示(slideToggleメソッド)
- 表示したmenu-subcontents以外のmenu-subcontentsをスライドさせて非表示(slideUpメソッド)
おわりに
たったこれだけのコーディングでもなんだか「それっぽいもの」が出来上がったので,若干嬉しく思います.これまで,jQueryの「$」に抵抗を感じてあまり触れてこなかったのですが,これを機におしゃれなページを作れたらいいなと思います.webデザインの書籍も読んでたりするんですが,センスがある程度必要な領域になっちゃうんでなかなか難しいですね....センスが欲しい.
今回の記事ですが,ちょっとやっつけで書いてしまったところがあるので,少しずつブラッシュアップしようかと思います.コードの説明を文章として書くのか,コメント見てくださいで済ませてしまうのかなど,いろいろふわふわしているので「これが分かりやすい」とかあったら教えていただきたいです.参考にします.
あと,hatenaでHTMLの表示結果をプレビューすることってできるんですかね.他のサイトを見ると結果のデモを同じページ上で表示している所があるので気になります.プラグインとかいろいろややこしいのかしら.知っている方がいらっしゃったらコメントでもtwitterのリプライでも教えていただけるとありがたいです.
最後になりますが,ここまでハンバーガーの綴りを間違えていたことに気が付きました.正しくは「hamburger」です.ずっと「hamberger」って書いてた….雰囲気で命名していることがばれてしまいましたが,ここもそのうち修正します.
それでは.
読んでくださった方に感謝を
マエカワ