javascript

ドロワーメニューをjQuery / javascriptのみで作る

よく使うドロワーメニューをjQueryまたは、javascriptのみで作ってみます。

ベースのHTML/CSS

よく使うドロワーメニューをjQueryを使って作成してみます。
また、jQueryを使わずjavascriptのみで全く同じドロワーメニューを作成してみます。

今回作成するものは、下記のページになります。jQueryを使って作成しています。

DEMO(jQueryバージョン)

ウインドウ幅を縮めて(767px以下)でご確認ください。

レスポンシブ対応になっているので、ウインドウ幅を767px以下で、右上にハンバーガメニューが表示されます。

まずはベースとなるHTMLとCSSについて解説します。

ソースは以下となります。

[HTML]一部抜粋

    <header class="header-sec">

        <img src="img/logo.svg" alt="" / class="header-logo">
        <nav>
          <ul class="header-ul flex">
            <li>
              <a href="#">Bangkok</a>
            </li>
            <li>
              <a href="#">Chiang Mai</a>
            </li>
            <li>
              <a href="#">Udon Thani</a>
            </li>
            <li>
              <a href="#">Chonburi</a>
            </li>
          </ul>
        </nav>

      <!-- ハンバーガーメニュー -->
      <div class="nav-ham" id="nav-toggle">
        <span></span>
        <span></span>
        <span></span>
      </div>
      

      <!-- #spnav -->
      <div class="sp-nav-layout" id="sp-nav">
        <nav>
          <ul>
            <li><a href="#">Bangkok</a></li>
            <li><a href="#">Chiang Mai</a></li>
            <li><a href="#">Udon Thani</a></li>
            <li><a href="#">Chonburi</a></li>
          </ul>
        </nav>
      </div>

    </header>

[CSS]一部抜粋

.inner {
  position: relative;
  width: 100%;
  max-width: 1000px;
  margin: 0 auto;
  padding: 0;
}

.flex {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}

/* body
--------------------------------*/

.header-sec {
  height: 126px;
  padding: 0 5%;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.header-logo {
  width: 107px;
  height: auto;
}

.header-ul {
  list-style: none;
  position: relative;
  display: flex;
}

.header-ul li {
  font-size: 1.6rem;
  margin-right: 45px;
}

.header-ul li a {
  display: block;
  color: #333;
  font-weight: bold;
  padding-bottom: 3px;
}

.header-ul li a:hover {
  color: #999;
  border-bottom: 1px solid #ccc;
  transition: 0s;
}

.header-ul li:last-child {
  margin-right: 0px;
}

.photo-sec {
  margin-top: 5%;
  margin-bottom: 5%;
}

.photo-box {
  width: 47.5%;
  margin-top: 5%;
}

.photo-box img {
  width: 100%;
  margin-bottom: 3.5%;
}

/* ハンバーガーメニュー */
.nav-ham {
  display: none;
  position: absolute;
  top: 2.2rem;
  right: 5.2%;
  width: 40px;
  height: 16px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  z-index: 100;
}

.nav-ham span {
  display: block;
  width: 100%;
  height: 2px;
  background-color: #333;
  position: absolute;
  transition: transform 0.5s, opacity 0.5s, width 0.3s;
}

.nav-ham span:nth-child(1) {
  top: 0;
}

.nav-ham span:nth-child(2) {
  top: 0;
  bottom: 0;
  margin: auto;
}

.nav-ham span:nth-child(3) {
  bottom: 0;
}

.sp-nav-layout {
  position: fixed;
  background: rgba(0, 0, 0, 0.9);
  top: 0;
  right: 0;
  width: 100%;
  height: 100vh;
  color: #ffffff;
  display: flex;
  justify-content: center;
  visibility: hidden;
  opacity: 0;
  transform: translateX(100%);
  transition: 0.5s ease-in-out;
  z-index: 50;
}

.sp-nav-layout ul {
  text-align: center;
  margin-top: 66%;
}

.sp-nav-layout ul li {
  position: relative;
  margin-bottom: 70px;
  transform: translateX(-200px);
  transition: transform 1.3s ease;
}

.sp-nav-layout ul li:nth-child(2) {
  transition-delay: 0.15s;
}

.sp-nav-layout ul li:nth-child(3) {
  transition-delay: 0.3s;
}

.sp-nav-layout ul li:nth-child(4) {
  transition-delay: 0.45s;
}

.sp-nav-layout ul li a {
  font-size: 24px;
  color: #fff;
}

@media only screen and (max-width: 767px) {

  /* body
--------------------------------*/
  .inner {
    position: relative;
    width: calc(100% - 40px);
    max-width: 1000px;
    margin: 0 auto;
    padding: 0;
  }
  .header-sec {
    height: 55px;
    padding: 0 20px;
  }
  .header-logo {
    width: 54px;
    height: auto;
  }
  .header-ul {
    display: none;
  }
  .photo-box p {
    font-size: 1.6rem;
  }
  .text-sec p {
    font-size: 1.6rem;
    line-height: 1.9;
  }
  /*sp nav*/
  .nav-ham {
    display: block;
    position: absolute;
    top: 20px;
    right: 20px;
    width: 20px;
    height: 16px;
    cursor: pointer;
    z-index: 100;
  }
  .open .nav-ham {
    position: fixed;
  }
  .open .nav-ham span {
    background-color: #fff;
  }
  .open .nav-ham span:nth-child(1) {
    transform: translateY(7px) rotate(45deg);
  }
  .open .nav-ham span:nth-child(2) {
    top: 0;
    bottom: 0;
    margin: auto;
    width: 0px;
    opacity: 0;
  }
  .open .nav-ham span:nth-child(3) {
    transform: translateY(-7px) rotate(-45deg);
  }
  .open .sp-nav-layout {
    visibility: visible;
    opacity: 1;
    transform: translateX(0);
  }
  .open .sp-nav-layout ul li {
    transform: translateX(0);
  }
  .overlay {
    content: "";
    display: block;
    width: 0;
    height: 0;
    background-color: rgba(0, 0, 0, 0.5);
    position: absolute;
    top: 0;
    left: 0;
    z-index: 2;
    opacity: 0;
    transition: opacity 0.5s;
  }
  .photo-sec {
    margin-top: 3rem;
    margin-bottom: 3rem;
  }
}

ソース全文見たい場合は、Chromeのディベロッパーツールなどを使用してDEMOページをご確認ください。

jQueryで書いた場合

次に[jQuery]のソースです。

[jQuery]

$(function () {
    $("#nav-toggle").on("click", function() {
        $("body").toggleClass("open");
    });
});

やっている事は、ハンバーガーメニューをクリックすると、HTMLのbodyタグにCSSのopenクラスが付与されます。

このbodyタグopenクラスを付けたり外したりをjQueryの[toggleClass]メソッドを使って行っています。

もともと(openクラスなし)の状態では、ドロワーメニューに、cssで[transform: translateX(100%);]と設定することで、ウインドウの右端に移動させておきます。

それにopenクラスを付けて、[transform: translateX(0);]と変化させることにより、メニューが右から左へとスライドして入ってくる動きを作っています。

あわせて、[opacity]を0から1へ、[visibility]hiddenからvisibilityへと書き換えています。

[visibility]に関しては以下のページで詳しく解説されています。

意外と知らないvisibilityの活用方法!(MITSUE-LINKS)

ドロワーメニューの中のメニュー(li)に対してopenクラスが付いたタイミングで、ベースのドロワーメニューとは逆に左から右へ[transform: translateX;]で移動させています。

一つ一つのメニュー(li)に対しても個別に[delay]をかけて、微妙に移動時間をづらしています。

javascriptで書いた場合

次にjQueryを使わず、javascriptのみで書いた場合になります。

DEMOでの見た目は、jQueryと同じです。

DEMO(javascriptバージョン)

ウインドウ幅を縮めて(767px以下)でご確認ください。

javascriptのコードです。

window.onload = function () {

  document.getElementById("nav-toggle").onclick = function () {
    document.querySelector("body").classList.toggle("open");
  };
  
};

やっている事はjQueryの時とほぼ同じです。

javascriptのみの場合は、[getElementById][querySelector]を使って要素を指定して、jQuery場合であれば[toggleClass]を使うところ、代わりに[classList.toggle]を使用します。

画像が重なりながら、横からスライドしてきて表示【Image SlideIn Effect】
【css】transitionの使い方【各プロパティ サンプルあり】
【CSSアニメーション】animationプロパティの使い方【サンプルあり】


-javascript

© 2021 MUKOLOG