0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

生JSでハンバーガーメニューを作ろう

Last updated at Posted at 2021-10-06

はじめに

過去にjQueryで実装したハンバーガーメニューを生のJavaScriptに書き換えた。
備忘録的な意味も込めて書いていく。
実はjQueryほとんど学習してないない
使わないから

仕様について

今回作成したハンバーガメニューはスマホ時のみ表示
aタグのhref属性に移動したいidを記入する
#とだけ記入すると画面最上部へスムーススクロールする
という条件で作成しています。

コード

jsだけだとどうしようもないのでhtmlとsassも貼っておく

HTML

<div id="hamburger__icon" class="hamburger__icon">
  <div class="hamburger__icon__bars">
    <div class="hamburger__icon__bars1"></div>
    <div class="hamburger__icon__bars2"></div>
    <div class="hamburger__icon__bars3"></div>
  </div>
</div>
      
<div id="hamburger__content" class="hamburger__content">
  <div class="hamburger__content-items">
    <div class="hamburger__content-item"><a href="">a</a></div>
    <div class="hamburger__content-item"><a href="">a</a></div>
    <div class="hamburger__content-item"><a href="">a</a></div>
    <div class="hamburger__content-item"><a href="">a</a></div>
    <div class="hamburger__content-item"><a href="">a</a></div>
  </div>
</div>
      
<div id="hamburger__background" class="hamburger__background"></div>

SASS

.hamburger__icon {
  position: fixed;
  top: 20px;
  right: 16px;
  z-index: 200;
  display: none;
  transition: 0.3s;

  @include mq('sp') {
    display: block;
  }

  &.active {
    transform: translateX(-200px);

    .hamburger__icon__bars1 {
      top: 8px;
      transform: rotate(-45deg);

    }
    
    .hamburger__icon__bars2 {
      display: none;
    }
    
    .hamburger__icon__bars3 {
      top: 8px;
      transform: rotate(45deg);
    }
  }
}

.hamburger__icon__bars {
  width: 22px;
  height: 20px;
  display: block;
  position: relative;
}

.hamburger__icon__bars1,
.hamburger__icon__bars2,
.hamburger__icon__bars3 {
  position: absolute;
  width: 22px;
  height: 4px;
  background: #fff;
  top: 0;
  left: 0;
  
}


.hamburger__icon__bars1 {
  top: 0;
}

.hamburger__icon__bars2 {
  top: 8px;
}

.hamburger__icon__bars3 {
  top: 16px;
}

.hamburger__content {
  width: 200px;
  height: 100%;
  background: #fff;
  position: fixed;
  top: 0;
  right: 0;
  box-shadow: 0 0 3px #00000029;
  z-index: 120;
  transform: translateX(105%);
  transition: 0.3s;


  &.active {
    transform: translateX(0%);
  }
}

.hamburger__content-items {

}

.hamburger__content-item {
  border-bottom: 1px dotted #707070;

  a {
    display: block;
    color: #707070;
    text-decoration: none;
    padding: 20px 145px 20px 20px;
  }
}

.hamburger__background {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 50;
  background: rgba(#000000, 0.8);
  display: none;
  transition: 0.3s;


  &.active {
    display: block;
  }
}

JavaScript

// スムーススクロール
document.querySelectorAll('a[href^="#"]').forEach(link => {
  link.addEventListener('click', function(e) {
    e.preventDefault();
    const header = document.getElementById('header').clientHeight,
          id = this.getAttribute('href');
    let position = 0;
    if(id !== "#") {
      position = window.pageYOffset + document.querySelector(id).getBoundingClientRect().top - header;
    }

    window.scrollTo({
      top: position,
      behavior: 'smooth'
    })

    //ハンバーガーメニューを押したらスクロールして消える
    if (document.getElementById('hamburger__content').classList.contains('active')) {
      const timerID = setInterval(() => {
        if (window.pageYOffset === position){
          clearInterval(timerID);
          document.getElementById('hamburger__icon').classList.remove('active')
          document.getElementById('hamburger__content').classList.remove('active')
          document.getElementById('hamburger__background').classList.remove('active')
        }
      }, 16)
    }

  })
})

//メニューの表示非表示
document.getElementById('hamburger__icon').addEventListener('click', function() {
  this.classList.toggle('active')
  document.getElementById('hamburger__content').classList.toggle('active')
  document.getElementById('hamburger__background').classList.toggle('active')
})

コードの説明

HTMLSASSは割愛。おしゃんなメニューです。
JavaScript

JSのコメントアウトを確認してください

  • スムーススクロール
    aタグのhref属性の値が#から始まる要素を取得して値に指定されているidへスムーススクロールする。
    移動距離をheaderの高さ分ずらす
    値に#だけが設定されている場合はページの最上部へスムーススクロールする

  • ハンバーガーメニューを押したらスクロールして消える
    メニューを押して移動した際、自動でハンバーガーメニューを閉じる

  • メニューの表示非表示
    メニューの表示非表示を切り替えるためのclassの付与を実行


カスタマイズ
上記に加えてお好みでカスタムしてください
マスク部分をクリックした場合ハンバーガーメニューを閉じます。
デフォルトではxアイコンを押した時/移動した時に閉じる

document.getElementById('hamburger__background').addEventListener('click', function() {
  this.classList.remove('active')
  document.getElementById('hamburger__icon').classList.remove('active')
  document.getElementById('hamburger__content').classList.remove('active')
})

おわりに

動かない場合はhtmlにidが付与されているか確認してください。
そういえば最近だと生JSを勉強するならTSもいいよと言われる。
Type Script人気ですよね。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?