2018年7月6日

デザイン

【js】jQueryでできるハンバーガーメニューの作成

jQueryでできるハンバーガーメニューの作成jQueryでできるハンバーガーメニューの作成

目次

  1. はじめに
  2. HTML / CSSの準備
  3. jQueryの記述
  4. まとめ

jQueryでできるハンバーガーメニューの作成.png (889.3 kB)

はじめに

本記事では、jQueryを使用したハンバーガーメニューの作成についてご紹介します。
スマートフォンのWebサイトでは一般的になったハンバーガーメニューを用いたサイドバーメニュー。
外部のjQueryプラグインを使用すれば手軽に実装できて便利かもしれませんが、
仕組みを理解することで必要な機能だけに絞ることや動作を軽快にすること、
自分で自由にカスタマイズできたりなど嬉しいこともたくさんあります!

サンプルコードを見ながら一緒に勉強しましょう!

今回作成するものはこちらになります!

See the Pen simple hamburger menu by takashi yamakawa (@y_taka520) on CodePen.

HTML / CSSの準備

まずはHTML / CSSの準備をしましょう。なお、本記事ではjQuery3.3.1を、アイコンにFontawesome 5を使用しています。

HTML

<header class="header">
  <i class="fas fa-bars header__icon"></i>
</header>
<main class="content">
  <h1 class="ttl">Title</h1>
  <p class="txt">(ここにテキストが入ります)</p>
  <h1 class="ttl">Title</h1>
  <p class="txt">(ここにテキストが入ります)</p>
  <h1 class="ttl">Title</h1>
  <p class="txt">(ここにテキストが入ります)</p>
</main>
<aside class="sidebar">
  <div class="sidebar__inner">
    <h2 class="sidebar__ttl">Menu</h2>
    <i class="fas fa-times-circle sidebar__icon"></i>
  </div>
  <p class="sidebar__txt">Menu 1</p>
  <p class="sidebar__txt">Menu 2</p>
  <p class="sidebar__txt">Menu 3</p>
  <p class="sidebar__txt">Menu 4</p>
  <p class="sidebar__txt">Menu 5</p>
</aside>
<div class="sidebar-bg"></div>

ソース中の<aside></aside>のなかがハンバーガーメニューで表示されるサイドバーになり、
<div class=”sidebar-bg”></div>がサイドバーの表示された際の背景になります。

CSS

/*reset*/
* {
  margin:0;
  padding:0;
}

/*header*/
.header {
  background-color:#558;
  height:48px;
  width:100%;
  position:fixed;
  top:0;
  left:0;
  display:flex;
  justify-content:flex-start;
  align-items:center;
  padding:0 16px;
  box-sizing:border-box;
  z-index:2;
}
.header__icon {
  color:#fff;
  font-size:28px;
}
.content {
  width:100vw;
  height:calc(100vh - 50px);
  position:absolute;
  top:50px;
  left:0;
  overflow-y:scroll;
  padding:0 16px;
  box-sizing:border-box;
}
.ttl {
  margin-top:32px;
  margin-bottom:16px;
}

/*sidebar*/
.sidebar {
  padding:16px;
  width:220px;
  height:100vh;
  position:fixed;
  background-color:#fff;
  top:0;
  left:-220px;
  z-index:4;
  box-shadow:0 0 10px rgba(0,0,0,0.5);
  box-sizing:border-box;
  display:none;
}
.sidebar__inner {
  display:flex;
  justify-content:space-between;
  align-items:center;
}
.sidebar__icon {
  font-size:28px;
  color:#654;
}
.sidebar__txt {
  font-size:18px;
  margin-top:16px;
  margin-left:8px;
}
.sidebar-bg {
  background-color:#558;
  width:100vw;
  height:100vh;
  opacity:0;
  position:fixed;
  top:0;
  left:0;
  z-index:3;
  display:none;
}

サイドバーのスタイルについて解説します。

サイドバーの開閉はpositionの値を操作して実装しています。
css側では閉じている状態のpositionの位置をします。

今回の例ではサイドバーが横220px × 縦100vhという大きさなので、positionのleftを-220pxにすることで左側の画面外に配置させておきます。

また今回はサイドバーにbox-shadowをつけているのでleftの値をサイドバーの横幅いっぱいにしてもはみ出てしまいます。そのため、通常時はdisplayをnoneにしてあげることではみ出さずに隠れてくれます。

ちなみにこのプロパティを最終的にはjQueryで値を制御するのですが、変更するプロパティが増えるのは面倒だという方はpositionのleftの値を-に増やしてbox-shadowが見えなくなるまで左側に寄せることでも対応可能です。

また、サイドバーの背景は横幅、縦幅共に画面いっぱいに設定し、こちらはopacityを0にdisplayをnoneにします。(理由は後ほど解説します。)
またサイドバー本体の下のレイヤーにくるようにz-indexの値を調整します。

POINT!!

・サイドバーはpositionで制御する
・サイドバーの横幅の大きさをpositionのleftに負の値で指定
・display:none;にしておく
・背景にはopacity:0;、display:none;を忘れずに

jQueryの記述

ここまでの準備ができたらいよいよjQueryで実装をしていきます。
jQuery

jQuery(document).ready(function(){
  /*open*/
  $('.header__icon').on('click',function(){
    $('.sidebar').css(
      'display','block'
    ).animate({
      left:'0'
    }, 
      300
    );
    $('.sidebar-bg').css(
      'display','block'
    ).animate({
      opacity:'0.5'
    },
      300
    )
  });
  /*close*/
  $('.sidebar__icon').on('click',function(){
    $('.sidebar').animate({
      left:'-200px'
    },
      300
    );
    $('.sidebar-bg').animate({
      opacity:'0'
    },
      300
    );
    setTimeout(function(){
      $('.sidebar').css('display','none');
      $('.sidebar-bg').css('display','none');
    },
      300
    );
  });
});

大きく分けて上半分が表示の時の処理、下半分が非表示にするときの処理になります。
まずは前半の表示処理について解説します。

表示処理について

まず3行目以下の

$('.header__icon').on('click',function(){ ... });

では.header__iconをクリックした時に{ }内の処理を実行するということを表しています。
その中には$(‘.sidebar’)と、$(‘.sidebar-bg’)の2種類のDOM要素に対して処理が実行されているのがわかります。

$(‘.sidebar’)側の処理
.sidebarにはまず.css()メソッドを使いプロパティ(スタイル)に変更をかけています。
今回の場合では.css( ‘display’, ‘block’ )でdisplayをnoneからblockに変更しています。

この.css()メソッドはCSSに直接変更を加えることができるのでとても便利です。
ただ便利な反面、変更するプロパティが増えれば増えるだけjQueryのコードは汚くなるので、多くなってきたら.addClass()メソッド.removeClass()メソッドを使いCSS側にスタイルを書きましょう。

.addClass()メソッドや.removeClass()メソッドについては前回作成したアコーディオンメニューで紹介してあるので、もしよかったらこちらも見てみると理解しやすいかもしれません。

【js】jQueryでできるアコーディオンメニューの作成

.css()メソッドの次に書いてあるのは.animate()メソッドです。
こちらは読んで字のごとくアニメーションを付与するメソッドになります。

.animate()メソッドには第一引数、第二引数を指定することができ、順に第一引数には動かしたい要素のスタイル第二引数でその変更が加えられるまでの時間を入力します。

.animate({第一引数(動かしたい要素のスタイル)}, 第二引数(時間));

今回ではpositionのleftの値をもともと-220pxから0pxに0.3秒(単位をつけない場合ms単位)で移動させる処理を行なっています。

ここで一つ疑問に思う方もいるのではないでしょうか。それは、

「だったら.css()メソッドを使わないで全て.animate()メソッドにかけばいいのではないのか?」

ということです。かくいう私もその1人でした。
.animate()メソッドに書くことができれば、コードもコンパクトになり綺麗になるのですが、.animate()メソッドで扱えるプロパティは値が数字にのもの限定です。

そのため今回のようなdisplay:blockといったものや他にも背景色を変更したいときは.animate()メソッドを使用することができないのでご注意ください。

$(‘.sidebar-bg’)側の処理
こちらも基本的には処理内容は.css()メソッドと.animate()メソッドのみのため細かい解説は割愛します。

先ほど説明しなかった背景に設定したopacty:0;とdisplay:none;についてですが、
どちらかだけでもぱっと見の見た目は変わらないため、一見するとわざわざ2つも設定する意味はないように見えます。
ですが、もしopacityのみを指定したら、本文の上に透明なレイヤーが常に表示されていることになり、操作することはできません。

またdisplay:none;のみを設定した場合、先に説明した.animate()メソッドでは扱えないため滑らかなアニメーションを実行することができません。

そのため2つのプロパティを設定する必要があります。

非表示処理について

こちらに関しても基本的には.css()メソッドと.animate()メソッドを使い表示アニメーションとは逆の処理を実行しています。
ここで表示アニメーションと違う項目としては

setTimeout(function(){ ... }, ... );

があります。これは設定した時間を経過したら中の処理を実行するという関数です。
第一引数{ … }のなかに実行する処理を入れ、
その後ろの第二引数で経過させる時間を入力します。

なぜsetTimeoutを使用したかは、
表示処理のように.css( … ).animate( … )と繋げて記述すると、同時に処理を実行するため、非表示の時にdisplay:none;が0秒のタイミングで発生してします。

これにより綺麗な非表示アニメーションにはなりません。

そのため、今回はsetTimeout関数を使用しています。

まとめ

今回は主に.css()メソッドと、.animate()メソッドという2つのメソッドを使ってサイドバーの実装をしました。
処理の流れを見ていくと理解しやすいと思うので、ぜひ勉強してみてはいかがでしょうか?

2

0

AUTHOR

yamakawa

やまかわたかし デザイナー

フロントエンドデザイナー。デザインからHTML / CSS、JSの実装を担当しています。最近はReact NativeやReact360をよく触っています。

アプリでもっと便利に!気になる記事をチェック!

記事のお気に入り登録やランキングが表示される昨日に対応!毎日の情報収集や調べ物にもっと身近なメディアになりました。

palanでは一緒に働く仲間を募集しています

正社員や業務委託、アルバイトやインターンなど雇用形態にこだわらず、
ベテランの方から業界未経験の方まで様々なかたのお力をお借りしたいと考えております。

話を聞いてみたい

運営メンバー

eishis

Eishi Saito 総務

SIerやスタートアップ、フリーランスを経て2016年11月にeishis, Inc.を設立。 マーケター・ディレクター・エンジニアなど何でも屋。 COBOLからReactまで色んなことやります。

sasakki デザイナー

アメリカの大学を卒業後、日本、シンガポールでデザイナーとして活動。

しまだ

しまだ デザイナー

WebAR/VRのデザインと3DCG制作がメインです。 肩書きは「アニメ案件に関わりたいデザイナー」。

Miu マーケター

ドイツでWEBマーケティングしています。

しんのき エンジニア

主に React Native を使ったアプリ開発と AWS や Firebase を使ったサーバーレスアーキテクチャを担当しています。元々はインフラとかPHPをやっていました。

yamakawa

やまかわたかし デザイナー

フロントエンドデザイナー。デザインからHTML / CSS、JSの実装を担当しています。最近はReact NativeやReact360をよく触っています。

furuya エンジニア

サーバーサイド、フロントエンド、Unityと色々手を出してる雑食系エンジニア。ReactNativeが最近のマイブーム。

Sayaka Osanai デザイナー

Sketchだいすきプロダクトデザイナー。シンプルだけどちょっとかわいいデザインが得意。 好きな食べものは生ハムとお寿司とカレーです。

はらた

はらた エンジニア

サーバーサイドエンジニア Ruby on Railsを使った開発を行なっています

うえまつゆい エンジニア

サーバーサイドエンジニアからフロントエンドエンジニアになりました。主にReact Nativeでのアプリ開発をしています。

kobori

こぼり ともろう エンジニア

サーバーサイドエンジニア。SIerを経て2019年7月に入社。日々学習しながらRuby on Railsを使った開発を行っています。

sasai

ささい エンジニア

フロントエンドエンジニア WebGLとReactが強みと言えるように頑張ってます。

damien

Damien

WebAR/VRを中心に企画やディレクションやエンジニアもちょっとやっています。森に住んでいます。

デザイナーゲスト

ゲスト デザイナー

CONTACT PAGE TOP