marco marco
marco marco

Reputation: 157

HAMBURGER MENU: Burger-icon and X-icon inconsistent toggling when clicked

I have this test page which I use to try to learn some Javascript.

I have a hamburger menu and what I want to do is: When I click the burger-icon, it disappears and the X-icon shows up and viceversa.

It works, but only for the first 'cycle' of toggling. It works only for 1 click on the burger-icon and the next click on the X-icon. After that, the X-icon doesn't show up anymore. Only the burger-icon.

NOTE: I started learning JS only a week ago and maybe, what I wrote in JS may be totally wrong or messy, but I wanted to test it based on what I learn and without looking for tutorials. What I wrote is based on what I thought it would be 'logical' :)

What did I do wrong?

//****** HIDE/SHOW NAV LINKS FOR BURGER-ICON
let burger = document.getElementById('burger');
let navBarLinks = document.getElementById('nav1');

burger.addEventListener('click', () => {
  navBarLinks.classList.toggle('active');
})



//****** HIDE/SHOW NAV LINKS FOR X-ICON
let xicon = document.getElementById('xicon');
xicon.addEventListener('click', () => {
  navBarLinks.classList.toggle('active');
})



//*******HIDE/SHOW BURGER-ICON/X-ICON ON CLICK
burger.addEventListener('click', () => {
  xicon.classList.toggle('show')
  burger.classList.toggle('hide')
})

xicon.addEventListener('click', () => {
  xicon.classList.toggle('hide')
  burger.classList.toggle('show')
})




//***** HIDE/SHOW NAVBAR ON SCROLL
const nav = document.querySelector('header');
let prevScrollpos = window.pageYOffset;

window.addEventListener('scroll', () => {
  let currentScrollpos = window.pageYOffset;

   if (prevScrollpos < currentScrollpos) {
     nav.classList.add('hide');
   }
   else {
     nav.classList.remove('hide');
   }

   prevScrollpos = currentScrollpos;
})
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  text-decoration: none;
  list-style: none;
}

:root {
  font-size: 15px;
}

header {
  overflow-x: hidden;
  transition: all .3s linear;
  transform: translateY(0px);
  position: fixed;
  z-index: 5;
}

.thing {
  position: relative;
  top: 64px;
}

header.hide {
  transform: translateY(-64.5px);
}

.logo {
  font-family: tahoma;
  font-size: 1.5rem;
}

.and {
  font-size: 1.1rem;
  font-family: sans-serif;
  position: relative;
  top: -1px;
}

.logoandburger {
  display: flex;
  width: 100vw;
  justify-content: space-between;
  align-items: center;
  background: linear-gradient(45deg,lightpink,powderblue);
  padding: 1em 1.5em;
  position: relative;
  z-index: 2;
}

.burger {
  position: absolute;
  left: 85%;
}

.burger.hide {
  display: none;
}

.burger.show {
  display: block;
}

.xicon {
  position: relative;
  left: -7px;
  display: none;
}

.xicon.show {
  display: block;
}

.xicon.hide {
  display: none;
}

.bubbles {
  position: relative;
  top: -8px;
  left: 80px;
  display: none;
}

@keyframes bubbly {
  from {
    transform: scale(.5);
    opacity: 0;
  }
  to {
    transform: scale(1.9);
    opacity: 1;
  }

}

.burger:active ~ .bubbles {
  display: block;
  animation: bubbly .2s linear;
}

.nav1 {
  background: linear-gradient(45deg,powderblue,lightpink);
  text-align: center;
  transform: translatex(100%) translateY(-110%);
  transition: .5s;
}

.nav1.active {
  transform: translatex(0%) translatey(0%);
}

ul {
  line-height: 2.5em;
  padding: 1em 0;
}

a {
  color: black;
  font-family: verdana;
  font-size: 1.2rem;
}
<header id="nav2">
    <div class="logoandburger">
      <h1 class="logo">Soap'n'Bubbles</h1>
      <img src="menu.svg" class="burger" id="burger" width="35px;" alt="menu icon">
      <img src="bubble.svg" class="bubbles" width="30px" alt="bubbles">
      <img src="xicon.svg" class="xicon" id="xicon" width="30px" alt="x icon">
    </div>
    <nav class="nav1" id="nav1">
      <ul class="nav">
        <li><a href="#">Home</a></li>
        <li><a href="#">Products</a></li>
        <li><a href="#">About Us</a></li>
        <li><a href="#">Contacts</a></li>
      </ul>
    </nav>

  </header>

  <h1 class="thing">Lorem ipsum dolor sit amet, consectetur adipisicing elit. At ut animi dicta ex, optio illo id perferendis ipsum quia repellat quam quis aut vel fugiat alias mollitia, architecto quos, delectus, eos. Blanditiis accusantium eum, culpa, dolores delectus voluptas officia eligendi! ipsum dolor sit amet, consectetur adipisicing elit. At ut animi dicta ex, optio illo id perferendis ipsum quia repellat quam quis aut vel fugiat alias mollitia, architecto quos, delectus, eos. Blanditiis accusantium eum, culpa, dolores delectus voluptas ipsum dolor sit amet, consectetur adipisicing elit. At ut animi dicta ex, optio illo id perferendis ipsum quia repellat quam quis aut vel fugiat alias mollitia, architecto quos, delectus, eos. Blanditiis accusantium eum, culpa, dolores delectus voluptas o illo id perferendis ipsum quia repellat quam quis aut vel fugiat alias mollitia, architecto quos, delectus, eos. Blanditiis accusantium eum, culpa, dolores delectus voluptas officia eligendi! ipsum dolor sit amet, consectetur adipisicing elit. At ut animi dicta ex, optio illo id perferendis ipsum quia repellat quam quis aut vel fugiat alias mollitia, architecto quos, delectus, eos. Blanditiis accusantium eum, culpa, dolores delectus voluptas ipsum dolor sit amet, consectetur adipisicing elit. At ut animi dicta ex, optio illo id perferendis ipsum quia repellat quam quis aut vel fugiat alias mollitia, architecto quos, delectus, eos. Blanditiis accusantium eum, culpa, dolores delectus volupt</h1>
<script src="main.js">

</script>

Upvotes: 1

Views: 198

Answers (2)

Alfred
Alfred

Reputation: 684

Toggle works, but in your first solution, you are toggling 2 different classes.

The way toggle works is if the class doesn't exist, add it, if it does, remove it.

If you just toggle the same class it would work.

burger.addEventListener('click', () => {
  xicon.classList.toggle('show')
  burger.classList.toggle('hide')
})

xicon.addEventListener('click', () => {
  xicon.classList.toggle('show')
  burger.classList.toggle('hide')
})

Upvotes: 1

marco marco
marco marco

Reputation: 157

SOLUTION FOUND

IMPORTANT: I don't know if this is correct or it is the right way to do it, but instead of using toggle I used add and remove.

Anybody know why it wasn't working with the toggle but it works with add and remove ?

//****** HIDE/SHOW NAV LINKS FOR BURGER-ICON
let burger = document.getElementById('burger');
let navBarLinks = document.getElementById('nav1');

burger.addEventListener('click', () => {
  navBarLinks.classList.toggle('active');
})



//****** HIDE/SHOW NAV LINKS FOR X-ICON
let xicon = document.getElementById('xicon');
xicon.addEventListener('click', () => {
  navBarLinks.classList.toggle('active');
})



//*******HIDE/SHOW BURGER-ICON/X-ICON ON CLICK
burger.addEventListener('click', () => {
  xicon.classList.add('show')
  burger.classList.add('hide')
})

xicon.addEventListener('click', () => {
  xicon.classList.remove('show')
  burger.classList.remove('hide')
})






//***** HIDE/SHOW NAVBAR ON SCROLL
const nav = document.querySelector('header');
let prevScrollpos = window.pageYOffset;

window.addEventListener('scroll', () => {
  let currentScrollpos = window.pageYOffset;

   if (prevScrollpos < currentScrollpos) {
     nav.classList.add('hide');
   }
   else {
     nav.classList.remove('hide');
   }

   prevScrollpos = currentScrollpos;
})
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  text-decoration: none;
  list-style: none;
}

:root {
  font-size: 15px;
}

header {
  overflow-x: hidden;
  transition: all .3s linear;
  transform: translateY(0px);
  position: fixed;
  z-index: 5;
}

.thing {
  position: relative;
  top: 64px;
}

header.hide {
  transform: translateY(-64.5px);
}

.logo {
  font-family: tahoma;
  font-size: 1.5rem;
}

.and {
  font-size: 1.1rem;
  font-family: sans-serif;
  position: relative;
  top: -1px;
}

.logoandburger {
  display: flex;
  width: 100vw;
  justify-content: space-between;
  align-items: center;
  background: linear-gradient(45deg,lightpink,powderblue);
  padding: 1em 1.5em;
  position: relative;
  z-index: 2;
}

.burger {
  position: absolute;
  left: 85%;
}

.burger.hide {
  display: none;
}

.burger.show {
  display: block;
}

.xicon {
  position: relative;
  left: -7px;
  display: none;
}

.xicon.show {
  display: block;
}

.xicon.hide {
  display: none;
}

.bubbles {
  position: relative;
  top: -8px;
  left: 80px;
  display: none;
}

@keyframes bubbly {
  from {
    transform: scale(.5);
    opacity: 0;
  }
  to {
    transform: scale(1.9);
    opacity: 1;
  }

}

.burger:active ~ .bubbles {
  display: block;
  animation: bubbly .2s linear;
}

.nav1 {
  background: linear-gradient(45deg,powderblue,lightpink);
  text-align: center;
  transform: translatex(100%) translateY(-110%);
  transition: .5s;
}

.nav1.active {
  transform: translatex(0%) translatey(0%);
}

ul {
  line-height: 2.5em;
  padding: 1em 0;
}

a {
  color: black;
  font-family: verdana;
  font-size: 1.2rem;
}
  <header id="nav2">
    <div class="logoandburger">
      <h1 class="logo">Soap'n'Bubbles</h1>
      <img src="menu.svg" class="burger" id="burger" width="35px;" alt="menu icon">
      <img src="bubble.svg" class="bubbles" width="30px" alt="bubbles">
      <img src="xicon.svg" class="xicon" id="xicon" width="30px" alt="x icon">
    </div>
    <nav class="nav1" id="nav1">
      <ul class="nav">
        <li><a href="#">Home</a></li>
        <li><a href="#">Products</a></li>
        <li><a href="#">About Us</a></li>
        <li><a href="#">Contacts</a></li>
      </ul>
    </nav>

  </header>

  <h1 class="thing">Lorem ipsum dolor sit amet, consectetur adipisicing elit. At ut animi dicta ex, optio illo id perferendis ipsum quia repellat quam quis aut vel fugiat alias mollitia, architecto quos, delectus, eos. Blanditiis accusantium eum, culpa, dolores delectus voluptas officia eligendi! ipsum dolor sit amet, consectetur adipisicing elit. At ut animi dicta ex, optio illo id perferendis ipsum quia repellat quam quis aut vel fugiat alias mollitia, architecto quos, delectus, eos. Blanditiis accusantium eum, culpa, dolores delectus voluptas ipsum dolor sit amet, consectetur adipisicing elit. At ut animi dicta ex, optio illo id perferendis ipsum quia repellat quam quis aut vel fugiat alias mollitia, architecto quos, delectus, eos. Blanditiis accusantium eum, culpa, dolores delectus voluptas o illo id perferendis ipsum quia repellat quam quis aut vel fugiat alias mollitia, architecto quos, delectus, eos. Blanditiis accusantium eum, culpa, dolores delectus voluptas officia eligendi! ipsum dolor sit amet, consectetur adipisicing elit. At ut animi dicta ex, optio illo id perferendis ipsum quia repellat quam quis aut vel fugiat alias mollitia, architecto quos, delectus, eos. Blanditiis accusantium eum, culpa, dolores delectus voluptas ipsum dolor sit amet, consectetur adipisicing elit. At ut animi dicta ex, optio illo id perferendis ipsum quia repellat quam quis aut vel fugiat alias mollitia, architecto quos, delectus, eos. Blanditiis accusantium eum, culpa, dolores delectus volupt</h1>
<script src="main.js">

</script>

Upvotes: 0

Related Questions