1

I created a burger menu which has the following JS:

const navSlide = () => {
  const burger = document.querySelector('.hamburger');
  const nav = document.querySelector('.nav-links');
  const navLinks = document.querySelectorAll('.nav-links li');

  burger.addEventListener('click', () => {
    // Open Menu
    burger.classList.toggle('no-shadow');
    nav.classList.toggle('nav-active');
    // Links fade efffect
    navLinks.forEach((link, index) => {
      if (link.style.animation) {
        link.style.animation = '';
      } else {
        link.style.animation = `navLinkFade .5s ease forwards ${index / 5 + .2}s`;
      }
      //ADDED
      link.addEventListener('click', () => {
        burger.classList.toggle('no-shadow');
        nav.classList.toggle('nav-active');
        burger.classList.toggle('toggle');
      });
      //ADDED
    });
    // Burger animation
    burger.classList.toggle('toggle');
  });
}
navSlide();
.nav-links {
    position: fixed;
    padding-top: 8rem;
    right: 0px;
    height: 70vh;
    top: 0;
    background-color: var(--branding);
    border-bottom-left-radius: 3rem;
    display: flex;
    flex-direction: column;
    text-align: left;
    padding: 3em;
    transform: translateX(100%);
    transition: transform .2s ease-in;
  }

  .nav-links li {
    opacity: 0;
  }

  .nav-links li a {
    font-size: 1rem ;
  }

.hamburger {
  margin: 1.5em;
  display: block;
  cursor: pointer;
  background-color: var(--branding);
  padding: 16px 12px;
  position: fixed;
  top: 0;
  right: 0;
  border-radius: 100%;
  box-shadow: 0 1.5rem 4rem rgba(0, 0, 0, .4);
}

.hamburger div {
  width: 25px;
  height: 2px;
  background-color: #d1d1d1;
  margin: 5px;
  transition: all .3s ease;
}

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

.no-shadow {
  box-shadow: none;
}

@keyframes navLinkFade {
  from {
    opacity: 0;
    transform: translateX(50px);
  }
  to {
    opacity: 1;
    transform: translateX(0px);
  }
}

.toggle .line1 {
  transform: rotate(-405deg) translate(-5px, 5px);
}

.toggle .line2 {
  opacity: 0;
}

.toggle .line3 {
  transform: rotate(405deg) translate(-5px, -5px);
}
<ul class="nav-links">
  <li><a href="#abt">About</a></li>
  <li><a href="#srv">Services</a></li>
  <li><a href="#soc">Social</a></li>
  <li><a href="#inf">Contact</a></li>
</ul>

  

<div class="hamburger">
   <div class="line1"></div>
   <div class="line2"></div>
   <div class="line3"></div>
</div>

Here's what I found relevant to upload and related with my issue, it's almost working as i want it to but, as i said it won't show the links after the menu closes the first time. I added the burger styles as Mark requested.

Let me know if you need anything else.

reekArd
  • 15
  • 5
  • Does this answer your question? [What do querySelectorAll and getElementsBy\* methods return?](https://stackoverflow.com/questions/10693845/what-do-queryselectorall-and-getelementsby-methods-return) – Mark Baijens Nov 17 '20 at 10:16
  • Thanks Mark, you made me think about it from a different perspective and I'm almost there. Now the issue is that when I open the menu again, the links are not there anymore... Why could that be? – reekArd Nov 17 '20 at 10:41
  • I updated my code as you can see above – reekArd Nov 17 '20 at 10:47
  • Can you create a snippet (`<>` icon) that reproduces your problem, with the html/css as well? – Mark Baijens Nov 17 '20 at 10:49
  • @MarkBaijens I updated my code. Let me know if you need anything else – reekArd Nov 17 '20 at 10:59
  • "...once I open it again" - ?? you mean once you **come back** to that page or **reload** the page?? – progyammer Nov 17 '20 at 11:00
  • @progyammer I meant that, once i click on a link, the menu dissapears as i want, but when i click on the burger icon again, the menu opens and the links are not there anymore – reekArd Nov 17 '20 at 11:04
  • I made a snippet of your code, as you can see it is still missing some code (hamburger element) to reproduce your issue. Please update the snippet so your problem is reproduced. – Mark Baijens Nov 17 '20 at 11:07
  • @MarkBaijens Thanks for helping out with that, I finally updated all my code and now we have a proper snippet to reproduce the issue – reekArd Nov 17 '20 at 11:22

1 Answers1

0

I moved the click event listener of the links outside of the burger click event listener to avoid duplicate event bindings. I also changed the event listener of the links to programmatically trigger the hamburger click to hide it again.

This way you don't have duplicated code. You want to avoid having to change code on 2 or more places when you change something.

const navSlide = () => {
  const burger = document.querySelector('.hamburger');
  const nav = document.querySelector('.nav-links');
  const navLinks = document.querySelectorAll('.nav-links li');

  //Toggle burger
  burger.addEventListener('click', () => {
    burger.classList.toggle('no-shadow');
    nav.classList.toggle('nav-active');
    navLinks.forEach((link, index) => {
      if (link.style.animation) {
        link.style.animation = '';
      } else {
        link.style.animation = `navLinkFade .5s ease forwards ${index / 5 + .2}s`;
      }
    });
    burger.classList.toggle('toggle');
  });
  
  //Moved outside the burger event listner to avoid duplicate event bindings and let the event listener programmatically trigger the burger click to hide it again.
  navLinks.forEach((link, index) => {
    link.addEventListener('click', () => {
      burger.click();
    });
  });
}
navSlide();
.nav-links {
  position: fixed;
  padding-top: 8rem;
  right: 0px;
  height: 70vh;
  top: 0;
  background-color: var(--branding);
  border-bottom-left-radius: 3rem;
  display: flex;
  flex-direction: column;
  text-align: left;
  padding: 3em;
  transform: translateX(100%);
  transition: transform .2s ease-in;
}

.nav-links li {
  opacity: 0;
}

.nav-links li a {
  font-size: 1rem;
}

.hamburger {
  margin: 1.5em;
  display: block;
  cursor: pointer;
  background-color: var(--branding);
  padding: 16px 12px;
  position: fixed;
  top: 0;
  right: 0;
  border-radius: 100%;
  box-shadow: 0 1.5rem 4rem rgba(0, 0, 0, .4);
}

.hamburger div {
  width: 25px;
  height: 2px;
  background-color: #d1d1d1;
  margin: 5px;
  transition: all .3s ease;
}

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

.no-shadow {
  box-shadow: none;
}

@keyframes navLinkFade {
  from {
    opacity: 0;
    transform: translateX(50px);
  }
  to {
    opacity: 1;
    transform: translateX(0px);
  }
}

.toggle .line1 {
  transform: rotate(-405deg) translate(-5px, 5px);
}

.toggle .line2 {
  opacity: 0;
}

.toggle .line3 {
  transform: rotate(405deg) translate(-5px, -5px);
}
<ul class="nav-links">
  <li><a href="#abt">About</a></li>
  <li><a href="#srv">Services</a></li>
  <li><a href="#soc">Social</a></li>
  <li><a href="#inf">Contact</a></li>
</ul>



<div class="hamburger">
  <div class="line1"></div>
  <div class="line2"></div>
  <div class="line3"></div>
</div>
Mark Baijens
  • 13,028
  • 11
  • 47
  • 73
  • 1
    That works like a charm Mark! I just need to understant how the .click() property works in there... I guess that it equals the click event on the navLinks with the click event on the burger icon right? – reekArd Nov 17 '20 at 11:41
  • @reekArd calling the `click()` function on an element will trigger the event like you click on it yourself. https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click – Mark Baijens Nov 17 '20 at 11:44