ウェブ

ハンバーガーメニューでメニュー外をクリックした際も閉じるを実行するナビゲーションの作り方【JavaScript】

ハンバーガーメニューでメニュー外をクリックした際も閉じるを実行するナビゲーションの作り方

端末の幅が狭い場合にハンバーガーメニューを表示しますが、PC版のサイトでもナビゲーションメニューが入りきらなかった時にも使用します。

メニューは白背景の部分でグレーにの箇所をクリックorタップでメニューが閉じる動作になります。

動作前
動作前
動作後
動作後

動作参考例

▪「Run Pen」をクリックで動作確認⇩

See the Pen 外部クリックで閉じる-ハンバーガーメニュー by pull-design (@design90806871) on CodePen.

クラスの取り外し

bodynav_openのクラスを付けて、ナビを表示してクラスがない場合は右側に隠している状態です。

クラスの取り外し

body.classList.toggle(“nav_open”);でクラスが付く。


body.classList.remove(“nav_open”);でクラスを外します。

JSに記述するコード⇩

//ハンバーガーメニュー
function toggleNav() {
  const body = document.body;
  const hamburger = document.getElementById("js_hamburger");
  const overlay = document.getElementById("js_overlay");
  hamburger.addEventListener("click", function () {
    body.classList.toggle("nav_open"); //クラスが含まれていれば削除、含まれていなければ追加する
  });
  overlay.addEventListener("click", function () {
    body.classList.remove("nav_open"); //クラスを削除する
  });
}
toggleNav();

classListについて

要素のクラス名を追加、削除、参照をすることができます。classListの後にメソッドを定義することにより、追加削除などの機能を指定することができます。

メソッド機能
addクラスを追加する
removeクラスを削除する
containsクラスが含まれているか確認する
toggleクラスが含まれていれば削除、含まれていなければ追加する
メソッド

コードまとめ

HTML

<!--ヘッダー↓-->
<header>
	<!-- pcハンバーガーメニュー ↓ -->
	<div class="pc_nav flex aic jcb">
		<h1><a href="#">rogo</a></h1>
		<div class="sp_no">
			<nav class="crumbs">
				<ul class="flex">
					<li><a href="">News</a></li>
					<li><a href="">About</a></li>
					<li><a href="">Service</a></li>
					<li><a href="">Works</a></li>
					<li><a href="">Contact</a></li>
				</ul>
			</nav>
		</div>
	</div>
	<!-- pcハンバーガーメニュー ↑ -->
	<!-- spハンバーガーメニュー ↓ -->
  <div class="sp_nav">
    <div class="overlay" id="js_overlay"></div>
    <div class="hamburger" id="js_hamburger">
      <span class="hamburger_linetop"></span>
      <span class="hamburger_linecenter"></span>
      <span class="hamburger_linebottom"></span>
    </div>
    <div class="sidemenu">
      <nav>
        <ul>
          <li><a href="">News</a></li>
          <li><a href="">About</a></li>
          <li><a href="">Service</a></li>
          <li><a href="">Works</a></li>
          <li><a href="">Contact</a></li>
        </ul>
      </nav>
    </div>
  </div>
	<!-- spハンバーガーメニュー ↑ -->
</header>
<!--ヘッダー↑-->

CSS

body,ul,li,h1,p {margin: 0;padding: 0;}
a {text-decoration: none; color: #000;}
li {list-style-type: none;}
/*------------------------------------
汎用 ↓
------------------------------------*/
.flex {display: flex;}
.aic {align-items: center;}
.jcb {justify-content: space-between;}
/*------------------------------------
ヘッダー a hover:下線アンダーライン ↓
------------------------------------*/
header ul li a {
  position: relative;
  display: inline-block;
  text-decoration: none;
}
header ul li a::after {
  position: absolute;
  bottom: -4px;
  left: 0;
  content: '';
  width: 100%;
  height: 3px;
  background: #3b5d82;
  transform: scale(0, 1);
  transform-origin: right top;
  transition: transform .3s;
}
header ul li a:hover {
  color: #3b5d82;
}
header ul li a:hover::after {
  transform-origin: left top;
  transform: scale(1, 1);
}
/*------------------------------------
ヘッダー pcハンバーガーメニュー ↓
------------------------------------*/
header {
  font-weight: 700;
}
header .pc_nav {
  margin: auto;
  width: 80%;
  padding-top: 40px;
}
header .pc_nav div .crumbs ul li {
  margin-right: 40px;
}
header .pc_nav div .crumbs ul li:last-of-type {
  margin-right: 0;
}
/*------------------------------------
ヘッダー spハンバーガーメニュー ↓
------------------------------------*/
header .sp_nav {
  text-align: center;
}
.sidemenu {
  height: 100vh;
  padding-top: 100px;
  position: fixed;
  right: -40%; /*メニュー幅*/
  transition: all 0.6s;
  top: 0;
  width: 40%; /*メニュー幅*/
  z-index: 2;
  background-color: #fff;
}
.sidemenu nav ul li {
  padding: 20px;
}
.hamburger {
  cursor: pointer;
  height: 60px;
  position: absolute;
  right: 30px;
  top: 30px;
  width: 60px;
  z-index: 3;
}
.hamburger span {
  background-color: #000;
  height: 4px;
  left: 15px;
  position: absolute;
  transition: all 0.6s;
  width: 30px;
}
.hamburger_linetop {
  top: 20px;
}
.hamburger_linecenter {
  top: 29px;
}
.hamburger_linebottom {
  top: 38px;
}
/*------------------------------------
メニュークリックした後 ↓
------------------------------------*/
.nav_open .sidemenu {
  right: 0;
}
.nav_open .hamburger_linetop {
  top: 26px;
  transform: rotate(45deg);
}
.nav_open .hamburger_linecenter {
  left: 50%;
  width: 0;
}
.nav_open .hamburger_linebottom {
  top: 26px;
  transform: rotate(-45deg);
}
.nav_open .overlay {
  opacity: 0.8;
  visibility: visible;
}
/*------------------------------------
メニュークリック後メニュー外の背景 ↓
------------------------------------*/
.overlay {
  background-color: #000;
  cursor: pointer;
  height: 100vh;
  left: 0;
  opacity: 0;
  position: fixed;
  top: 0;
  transition: all 0.6s;
  visibility: hidden;
  width: 100vw;
  z-index: 1;
}
/*------------------------------------
@media screen 1000px~999px ↓
------------------------------------*/
@media screen and (max-width: 1000px) {
  .sp_no {
    display: none;
  }
  .sidemenu {
    right: -50%; /*メニュー幅*/
    width: 50%; /*メニュー幅*/
  }
}
@media screen and (min-width: 999px) {
  .pc_no {
    display: none;
  }
}

JS

//ハンバーガーメニュー
function toggleNav() {
  const body = document.body;
  const hamburger = document.getElementById("js_hamburger");
  const overlay = document.getElementById("js_overlay");
  hamburger.addEventListener("click", function () {
    body.classList.toggle("nav_open"); //クラスを追加する
  });
  overlay.addEventListener("click", function () {
    body.classList.remove("nav_open"); //クラスを削除する
  });
}
toggleNav();

スクロールを固定するハンバーガーメニュー

下記記事はメニューが開かれているときはスクロールを固定するパターン⇩

ハンバーガーメニュー
ハンバーガーメニューをコピペで簡単実装【HTML・CSS・jQuery】1150px以上はナビゲーションメニューを全部表示、1150px以下はメニューを非表示にしておいて、クリックorタップで表示させるようにする設定が必要です。...

ハンバーガーメニューとフルスクリーントップ画像をズームを組み合わせする方法についての記事になります⇩

swiper_html
フルスクリーントップ画像をズームしながら全画面で切り替えSwiper組み合わせハンバーガーメニュー付きフルスクリーントップ画像をズームしながら画像を切り替えるSwiper導入とハンバーガーメニューを同時にコピーペーストで実装できるように記事にしました。...