简体   繁体   中英

Responsive Navigation Hamburger Menu not working

I'm trying to make my navigation responsive but when i tried to resize my window, my hamburger doesn't allow the dropdown function to work. I took both the navigation and responsive hamburger online so is there somewhere that might be overwriting the hamburger?

This is my HTML

<header>
  <div class="logo">
    <p>LEGEND</p>
    <div class= "hamburger">
      <div class="line"></div>
      <div class="line"></div>
      <div class="line"></div>
    </div>
  </div>
  <nav class="nav-bar">
    <ul>
      <li><a href="#">HOME</a></li>
      <li><a href="#">STORE</a></li>
      <li><a href="#">MY ACCOUNT</a></li>
      <li><a href="#">SEARCH</a></li>
    </ul>
  </nav>
  <button>
  <a href="#">
  <h4 style="color: #f5f5f5">PLAY DIVINE</h4>
  </a>
  </button>
</header>

This is my css

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
body {
    background-color: #12171c;
}
header {
    width: 100%;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 10px 10%;
    background: rgba(0, 0, 0, 0.2);
    position: fixed;
    height: 10%;
}
.logo {
    font-size: 30px;
    font-weight: bold;
    color: white;
    letter-spacing: 1.5px;
    cursor: pointer;
}
.nav-bar li {
    display: inline-block;
    list-style: none;
    padding: 0px 15px;
}
a, button {
    font-size: 16px;
    font-weight: 500;
    color: #b7b9bb;
    text-decoration: none;
    cursor: pointer;
}
button {
    background: #967526;
    border: 2px solid #ffce1f;
    padding: 9px 25px;
}
.header-pic {
    width: 100%;
    height: 100%;
    background-size: cover;
}
.hamburger {
    display: none;
}

This is my css when it's responsive

@media only screen and (max-width: 1320px) {
.hamburger {
    display: block;
    cursor: pointer;
}
.hamburger .line {
    width: 30px;
    height: 3px;
    background: #fefefe;
    margin: 6px 0;
}
.nav-bar {
    height: 0;
    position: absolute;
    top: 80px;
    left: 0;
    right: 0;
    width: 100vw;
    background: #11101b;
    transition: 0.2s;
    overflow: hidden;
}
.nav-bar.active {
    height: 450px;
}
.nav-bar ul {
    display: block;
    width: fit-content;
    margin: 80px auto 0 auto;
    text-align: center;
    transition: 0.5s;
    opacity: 0;
}
.nav-bar.active ul {
    opacity: 1;
}
.nav-bar ul li a {
    margin-botton: 12px;
}
}

This is my javascript

<script>
 hamburger = document.querySelector(".hamburger");
 hamburger.onClick = function() {
  navBar = document.querySelector(".nav-bar");
  navbar.classList.toggle("active");
  }
 </script>

Your code has nothing wrong, just few typos in your JavaScript:

  1. You have onClick instead of onclick
  2. navbar instead of navBar at navbar.classList.toggle("active")

Corrected version

<script>
  hamburger = document.querySelector(".hamburger");
  hamburger.onclick = function() {
    navBar = document.querySelector(".nav-bar");
    navBar.classList.toggle("active");
  }
</script>

Extra ( Change display: block; to display: grid; in .nav-bar ul selector in CSS media query to display dropdown in vertical list )

.nav-bar ul {
  display: grid;
  width: fit-content;
  margin: 80px auto 0 auto;
  text-align: center;
  transition: 0.5s;
  opacity: 0;
}

 hamburger = document.querySelector(".hamburger"); hamburger.onclick = function() { navBar = document.querySelector(".nav-bar"); navBar.classList.toggle("active"); }
 * { margin: 0; padding: 0; box-sizing: border-box; } body { background-color: #12171c; } header { width: 100%; display: flex; justify-content: space-between; align-items: center; padding: 10px 10%; background: rgba(0, 0, 0, 0.2); position: fixed; height: 10%; }.logo { font-size: 30px; font-weight: bold; color: white; letter-spacing: 1.5px; cursor: pointer; }.nav-bar li { display: inline-block; list-style: none; padding: 0px 15px; } a, button { font-size: 16px; font-weight: 500; color: #b7b9bb; text-decoration: none; cursor: pointer; } button { background: #967526; border: 2px solid #ffce1f; padding: 9px 25px; }.header-pic { width: 100%; height: 100%; background-size: cover; }.hamburger { display: none; } @media only screen and (max-width: 1320px) {.hamburger { display: block; cursor: pointer; }.hamburger.line { width: 30px; height: 3px; background: #fefefe; margin: 6px 0; }.nav-bar { height: 0; position: absolute; top: 80px; left: 0; right: 0; width: 100vw; background: #11101b; transition: 0.2s; overflow: hidden; }.nav-bar.active { height: 450px; }.nav-bar ul { display: grid; width: fit-content; margin: 80px auto 0 auto; text-align: center; transition: 0.5s; opacity: 0; }.nav-bar.active ul { opacity: 1; }.nav-bar ul li a { margin-bottom: 12px; } }
 <header> <div class="logo"> <p>LEGEND</p> <div class="hamburger"> <div class="line"></div> <div class="line"></div> <div class="line"></div> </div> </div> <nav class="nav-bar"> <ul> <li><a href="#">HOME</a></li> <li><a href="#">STORE</a></li> <li><a href="#">MY ACCOUNT</a></li> <li><a href="#">SEARCH</a></li> </ul> </nav> <button> <a href="#"> <h4 style="color: #f5f5f5">PLAY DIVINE</h4> </a> </button> </header>


Better Solution

Quote from MDN Web Docs, as in this link :

The recommended mechanism for adding event handlers in web pages is the addEventListener() method

You may use addEventListener() to achieve the same result:

<script>
  hamburger = document.querySelector(".hamburger");
  hamburger.addEventListener("click", () => {
    navBar = document.querySelector(".nav-bar");
    navBar.classList.toggle("active");
  });
</script>

 hamburger = document.querySelector(".hamburger"); hamburger.addEventListener("click", () => { navBar = document.querySelector(".nav-bar"); navBar.classList.toggle("active"); });
 * { margin: 0; padding: 0; box-sizing: border-box; } body { background-color: #12171c; } header { width: 100%; display: flex; justify-content: space-between; align-items: center; padding: 10px 10%; background: rgba(0, 0, 0, 0.2); position: fixed; height: 10%; }.logo { font-size: 30px; font-weight: bold; color: white; letter-spacing: 1.5px; cursor: pointer; }.nav-bar li { display: inline-block; list-style: none; padding: 0px 15px; } a, button { font-size: 16px; font-weight: 500; color: #b7b9bb; text-decoration: none; cursor: pointer; } button { background: #967526; border: 2px solid #ffce1f; padding: 9px 25px; }.header-pic { width: 100%; height: 100%; background-size: cover; }.hamburger { display: none; } @media only screen and (max-width: 1320px) {.hamburger { display: block; cursor: pointer; }.hamburger.line { width: 30px; height: 3px; background: #fefefe; margin: 6px 0; }.nav-bar { height: 0; position: absolute; top: 80px; left: 0; right: 0; width: 100vw; background: #11101b; transition: 0.2s; overflow: hidden; }.nav-bar.active { height: 450px; }.nav-bar ul { display: grid; width: fit-content; margin: 80px auto 0 auto; text-align: center; transition: 0.5s; opacity: 0; }.nav-bar.active ul { opacity: 1; }.nav-bar ul li a { margin-bottom: 12px; } }
 <header> <div class="logo"> <p>LEGEND</p> <div class="hamburger"> <div class="line"></div> <div class="line"></div> <div class="line"></div> </div> </div> <nav class="nav-bar"> <ul> <li><a href="#">HOME</a></li> <li><a href="#">STORE</a></li> <li><a href="#">MY ACCOUNT</a></li> <li><a href="#">SEARCH</a></li> </ul> </nav> <button> <a href="#"> <h4 style="color: #f5f5f5">PLAY DIVINE</h4> </a> </button> </header>


Alternate Solution

For readers who are more familiar to add() / remove() , here's some alternatives:

<script>
  hamburger = document.querySelector(".hamburger");
  hamburger.addEventListener("click", () => {
    navBar = document.querySelector(".nav-bar");
    if (navBar.classList.contains("active")) {
      navBar.classList.remove("active");
    } else {
      navBar.classList.add("active");
    }
  });
</script>

 hamburger = document.querySelector(".hamburger"); hamburger.addEventListener("click", () => { navBar = document.querySelector(".nav-bar"); if (navBar.classList.contains("active")) { navBar.classList.remove("active"); } else { navBar.classList.add("active"); } });
 * { margin: 0; padding: 0; box-sizing: border-box; } body { background-color: #12171c; } header { width: 100%; display: flex; justify-content: space-between; align-items: center; padding: 10px 10%; background: rgba(0, 0, 0, 0.2); position: fixed; height: 10%; }.logo { font-size: 30px; font-weight: bold; color: white; letter-spacing: 1.5px; cursor: pointer; }.nav-bar li { display: inline-block; list-style: none; padding: 0px 15px; } a, button { font-size: 16px; font-weight: 500; color: #b7b9bb; text-decoration: none; cursor: pointer; } button { background: #967526; border: 2px solid #ffce1f; padding: 9px 25px; }.header-pic { width: 100%; height: 100%; background-size: cover; }.hamburger { display: none; } @media only screen and (max-width: 1320px) {.hamburger { display: block; cursor: pointer; }.hamburger.line { width: 30px; height: 3px; background: #fefefe; margin: 6px 0; }.nav-bar { height: 0; position: absolute; top: 80px; left: 0; right: 0; width: 100vw; background: #11101b; transition: 0.2s; overflow: hidden; }.nav-bar.active { height: 450px; }.nav-bar ul { display: grid; width: fit-content; margin: 80px auto 0 auto; text-align: center; transition: 0.5s; opacity: 0; }.nav-bar.active ul { opacity: 1; }.nav-bar ul li a { margin-bottom: 12px; } }
 <header> <div class="logo"> <p>LEGEND</p> <div class="hamburger"> <div class="line"></div> <div class="line"></div> <div class="line"></div> </div> </div> <nav class="nav-bar"> <ul> <li><a href="#">HOME</a></li> <li><a href="#">STORE</a></li> <li><a href="#">MY ACCOUNT</a></li> <li><a href="#">SEARCH</a></li> </ul> </nav> <button> <a href="#"> <h4 style="color: #f5f5f5">PLAY DIVINE</h4> </a> </button> </header>


UPDATE

I revised the solution so that the 2 blocks are for:

  1. In small screen but active is not on
  2. In small screen and active is on

This separation protects the style from broken when transition happen as active toggles.

More styles can be added to the first block to define how this list should look like, such as making it display the list in column.

Example:

.nav-bar ul {
  display: flex;
  flex-direction: column;
  width: fit-content;
  margin: 80px auto 0 auto;
  text-align: center;
  transition: 0.5s;
  opacity: 0;
}

.nav-bar.active ul {
  opacity: 1;
}

Original

This is because your JS code has some syntax error. Here is what to do:

  1. Use const to declare hamburger and navbar .
  2. Call addEventListener on hamburger to add the function for toggling class of navbar

Follow the below example to revise your code, or visit a live demo of it fixed here: codepen

const hamburger = document.querySelector(".hamburger");
const navbar = document.querySelector(".nav-bar");
hamburger.addEventListener("click", () => navbar.classList.toggle("active"));

Hope this solution will help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM