Search code examples
javascripthtmlnav

Close nav on link click


My nav closes when a user clicks the "X" or hits the esc key, I would like it to close when a user clicks a link as well. The nav is constructed as such;

<div class="top-bar">
        <button class="top-bar__nav-toggle hamburger" id="top-nav-toggle">
          <span></span>
          <span></span>
          <span></span>
        </button>
        <nav class="top-bar__nav collapsed" id="top-bar__nav">
          <ul class="top-bar__nav-list nav-ul">
            <li>
              <a class="navlink" href="#">Home</a>
            </li>
            <li>
              <a class="navlink" href="#Portfolio">Work</a>
            </li>
            <li>
              <a class="navlink" href="#About">About</a>
            </li>
            <li>
              <a class="navlink" href="#Contact">Contact</a>
            </li>
          </ul>
        </nav>
      </div>

is styled as such;

body {
  background: gray;
}
.top-bar {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  margin-right: 2vw;
}

.top-bar__nav-toggle {
  background: transparent;
  border: none;
  cursor: pointer;
  display: none;
  font-size: 50px;
  min-width: 5vw;
  text-align: center;
  transition: 0.25s;
}

.hamburger {
  height: 4vw;
  position: relative;
}

.hamburger span {
  background: white;
  border-radius: 25%;
  height: 2px;
  position: absolute;
  transform: translate(-50%, -50%);
  width: 4vw;
}

.hamburger:focus span {
  background: rgb(91, 196, 221);
  outline: none;
}

.hamburger:hover span {
  background: rgb(91, 196, 221);
}

.hamburger span:nth-child(1) {
  top: 20%;
  transition: top 125ms 250ms, transform 125ms;
}
.hamburger span:nth-child(2) {
  top: 50%;
  transition: top 125ms 250ms, transform 125ms;
}
.hamburger span:nth-child(3) {
  top: 80%;
  transition: top 125ms 250ms, transform 125ms;
}

.hamburger.closed span:nth-child(1) {
  top: 50%;
  transform: translate(-50%, -50%) rotate(45deg);
  transition: top 125ms, transform 125ms 250ms;
}
.hamburger.closed span:nth-child(2) {
  top: 50%;
  transform: translate(-50%, -50%) rotate(-45deg);
  transition: top 125ms, transform 125ms 250ms;
}
.hamburger.closed span:nth-child(3) {
  top: 50%;
  transform: translate(-50%, -50%) rotate(-45deg);
  transition: top 125ms, transform 125ms 250ms;
}

.nav-ul {
  display: flex;
  justify-content: center;
  list-style-type: none;
  padding: 0;
}

.top-bar__nav {
  background: transparent;
  max-height: 400px;
  overflow: hidden;
  transition: 0.25s;
  width: 100%;
}

.top-bar__nav.collapsed .top-bar__nav-list {
  transition: all ease-in-out 1s;
}

.top-bar__nav-list {
  list-style: none;
}

.top-bar__nav-list li {
  text-align: center;
}

.collapsed .top-bar__nav-list a {
  font-size: 2vw;
}

.top-bar__nav-list a {
  border-bottom: 2px solid transparent;
  color: white;
  display: inline-block;
  font-size: 6vw;
  padding-left: 3vw;
  text-decoration: none;
  transition: 0.25s;
}

.top-bar__nav-list a:hover {
  color: rgb(91, 196, 221);
}

.top-bar__nav-list a:focus {
  color: rgb(91, 196, 221);
  outline: none;
}

@media screen and (max-width: 500px) {
  .top-bar__nav-list {
    align-items: flex-end;
    background: white;
    flex-direction: column;
    height: 100%;
    max-height: 100%;
    overflow: hidden;
    padding-right: 4vw;
    position: fixed;
    transition: all ease-in-out 1s;
        -webkit-transform: translateZ(0);
    -moz-transform: translateZ(0);
    -ms-transform: translateZ(0);
    -o-transform: translateZ(0);
    transform: translateZ(0);
    right: 0;
    width: 100%;
  }

  .top-bar__nav.collapsed .top-bar__nav-list {
    max-height: 0;
  }

  .top-bar__nav-list.collapsed {
    padding-right: 6vw;
  }

  .nav-ul li a {
    color: gray;
  }

  .top-bar__nav-toggle {
    display: inline-block;
  body {
  background: gray;
}
.top-bar {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  margin-right: 2vw;
}

.top-bar__nav-toggle {
  background: transparent;
  border: none;
  cursor: pointer;
  display: none;
  font-size: 50px;
  min-width: 5vw;
  text-align: center;
  transition: 0.25s;
}

.hamburger {
  height: 4vw;
  position: relative;
}

.hamburger span {
  background: white;
  border-radius: 25%;
  height: 2px;
  position: absolute;
  transform: translate(-50%, -50%);
  width: 4vw;
}

.hamburger:focus span {
  background: rgb(91, 196, 221);
  outline: none;
}

.hamburger:hover span {
  background: rgb(91, 196, 221);
}

.hamburger span:nth-child(1) {
  top: 20%;
  transition: top 125ms 250ms, transform 125ms;
}
.hamburger span:nth-child(2) {
  top: 50%;
  transition: top 125ms 250ms, transform 125ms;
}
.hamburger span:nth-child(3) {
  top: 80%;
  transition: top 125ms 250ms, transform 125ms;
}

.hamburger.closed span:nth-child(1) {
  top: 50%;
  transform: translate(-50%, -50%) rotate(45deg);
  transition: top 125ms, transform 125ms 250ms;
}
.hamburger.closed span:nth-child(2) {
  top: 50%;
  transform: translate(-50%, -50%) rotate(-45deg);
  transition: top 125ms, transform 125ms 250ms;
}
.hamburger.closed span:nth-child(3) {
  top: 50%;
  transform: translate(-50%, -50%) rotate(-45deg);
  transition: top 125ms, transform 125ms 250ms;
}

.nav-ul {
  display: flex;
  justify-content: center;
  list-style-type: none;
  padding: 0;
}

.top-bar__nav {
  background: transparent;
  max-height: 400px;
  overflow: hidden;
  transition: 0.25s;
  width: 100%;
}

.top-bar__nav.collapsed .top-bar__nav-list {
  transition: all ease-in-out 1s;
}

.top-bar__nav-list {
  list-style: none;
}

.top-bar__nav-list li {
  text-align: center;
}

.collapsed .top-bar__nav-list a {
  font-size: 2vw;
}

.top-bar__nav-list a {
  border-bottom: 2px solid transparent;
  color: white;
  display: inline-block;
  font-size: 6vw;
  padding-left: 3vw;
  text-decoration: none;
  transition: 0.25s;
}

.top-bar__nav-list a:hover {
  color: rgb(91, 196, 221);
}

.top-bar__nav-list a:focus {
  color: rgb(91, 196, 221);
  outline: none;
}

@media screen and (max-width: 500px) {
  .top-bar__nav-list {
    align-items: flex-end;
    background: white;
    flex-direction: column;
    height: 100%;
    max-height: 100%;
    overflow: hidden;
    padding-right: 4vw;
    position: fixed;
    transition: all ease-in-out 1s;
        -webkit-transform: translateZ(0);
    -moz-transform: translateZ(0);
    -ms-transform: translateZ(0);
    -o-transform: translateZ(0);
    transform: translateZ(0);
    right: 0;
    width: 100%;
  }

  .top-bar__nav.collapsed .top-bar__nav-list {
    max-height: 0;
  }

  .top-bar__nav-list.collapsed {
    padding-right: 6vw;
  }

  .nav-ul li a {
    color: gray;
  }

  .top-bar__nav-toggle {
    display: inline-block;
  }

and its functionality comes from this code;

(function () {
  if (document.querySelector("#top-nav-toggle")) {
    var navToggle = document.querySelector("#top-nav-toggle");

    function watchNavClose(e) {
      var topNav = document.querySelector(".top-bar");
      if (!e.path.includes(topNav)) {
        openCloseNav();
        document.documentElement.removeEventListener("click", watchNavClose);
      }
    }

    function openCloseNav() {
      var navToggle = document.querySelector("#top-nav-toggle");

      if (!navToggle.classList.contains("closed")) {
        navToggle.classList.add("closed");
        document.querySelector("#top-bar__nav").classList.remove("collapsed");
        document.querySelector("html").addEventListener("click", watchNavClose);
        document.body.style.overflowY = 'hidden';
      } else {
        document.querySelector("#top-bar__nav").classList.add("collapsed");
        document.documentElement.removeEventListener("click", watchNavClose);
        document.body.style.overflowY = "scroll";
        navToggle.classList.remove("closed");
        }
      }

      document.addEventListener('keydown', e => {
        if ( e.keyCode === 27 ) {
          document.documentElement.removeEventListener("click", watchNavClose);
          document.body.style.overflowY = "scroll";
          navToggle.classList.remove("closed");
          document.querySelector("#top-bar__nav").classList.add("collapsed");
        }
      })

      navToggle.addEventListener("click", openCloseNav);
  }
})

();

I am mostly building through tutorials and such and I have tried figuring it out through similar questions here, but I am new to this and couldn't figure out how to translate it to my code. Any help is appreciated.


Solution

  • Added separate event listners for the <a> tag using querySelectorAll and run a function which closes nav on listening to click event

    (function() {
      if (document.querySelector("#top-nav-toggle")) {
        var navToggle = document.querySelector("#top-nav-toggle");
    
        function watchNavClose(e) {
          var topNav = document.querySelector(".top-bar");
          if (!e.path.includes(topNav)) {
            openCloseNav();
            document.documentElement.removeEventListener("click", watchNavClose);
          }
        }
    
        function openCloseNav() {
          var navToggle = document.querySelector("#top-nav-toggle");
    
          if (!navToggle.classList.contains("closed")) {
            navToggle.classList.add("closed");
            document.querySelector("#top-bar__nav").classList.remove("collapsed");
            document.querySelector("html").addEventListener("click", watchNavClose);
            document.body.style.overflowY = 'hidden';
          } else {
            document.querySelector("#top-bar__nav").classList.add("collapsed");
            document.documentElement.removeEventListener("click", watchNavClose);
            document.body.style.overflowY = "scroll";
            navToggle.classList.remove("closed");
          }
        }
    
        document.addEventListener('keydown', e => {
          if (e.keyCode === 27) {
            document.documentElement.removeEventListener("click", watchNavClose);
            document.body.style.overflowY = "scroll";
            navToggle.classList.remove("closed");
            document.querySelector("#top-bar__nav").classList.add("collapsed");
          }
        })
    
        navToggle.addEventListener("click", openCloseNav);
    
        document.querySelectorAll(".navlink")[0].addEventListener("click", closeNav);
        document.querySelectorAll(".navlink")[1].addEventListener("click", closeNav);
        document.querySelectorAll(".navlink")[2].addEventListener("click", closeNav);
        document.querySelectorAll(".navlink")[3].addEventListener("click", closeNav);
    
        function closeNav() {
          var navToggle = document.querySelector("#top-nav-toggle");
          document.querySelector("#top-bar__nav").classList.add("collapsed");
          document.documentElement.removeEventListener("click", watchNavClose);
          document.body.style.overflowY = "scroll";
          navToggle.classList.remove("closed");
        }
    
      }
    })
    
    ();
          body {
      background: gray;
    }
    
    .top-bar {
      align-items: center;
      display: flex;
      flex-wrap: wrap;
      margin-right: 2vw;
    }
    
    .top-bar__nav-toggle {
      background: transparent;
      border: none;
      cursor: pointer;
      display: none;
      font-size: 50px;
      min-width: 5vw;
      text-align: center;
      transition: 0.25s;
    }
    
    .hamburger {
      height: 4vw;
      position: relative;
    }
    
    .hamburger span {
      background: white;
      border-radius: 25%;
      height: 2px;
      position: absolute;
      transform: translate(-50%, -50%);
      width: 4vw;
    }
    
    .hamburger:focus span {
      background: rgb(91, 196, 221);
      outline: none;
    }
    
    .hamburger:hover span {
      background: rgb(91, 196, 221);
    }
    
    .hamburger span:nth-child(1) {
      top: 20%;
      transition: top 125ms 250ms, transform 125ms;
    }
    
    .hamburger span:nth-child(2) {
      top: 50%;
      transition: top 125ms 250ms, transform 125ms;
    }
    
    .hamburger span:nth-child(3) {
      top: 80%;
      transition: top 125ms 250ms, transform 125ms;
    }
    
    .hamburger.closed span:nth-child(1) {
      top: 50%;
      transform: translate(-50%, -50%) rotate(45deg);
      transition: top 125ms, transform 125ms 250ms;
    }
    
    .hamburger.closed span:nth-child(2) {
      top: 50%;
      transform: translate(-50%, -50%) rotate(-45deg);
      transition: top 125ms, transform 125ms 250ms;
    }
    
    .hamburger.closed span:nth-child(3) {
      top: 50%;
      transform: translate(-50%, -50%) rotate(-45deg);
      transition: top 125ms, transform 125ms 250ms;
    }
    
    .nav-ul {
      display: flex;
      justify-content: center;
      list-style-type: none;
      padding: 0;
    }
    
    .top-bar__nav {
      background: transparent;
      max-height: 400px;
      overflow: hidden;
      transition: 0.25s;
      width: 100%;
    }
    
    .top-bar__nav.collapsed .top-bar__nav-list {
      transition: all ease-in-out 1s;
    }
    
    .top-bar__nav-list {
      list-style: none;
    }
    
    .top-bar__nav-list li {
      text-align: center;
    }
    
    .collapsed .top-bar__nav-list a {
      font-size: 2vw;
    }
    
    .top-bar__nav-list a {
      border-bottom: 2px solid transparent;
      color: white;
      display: inline-block;
      font-size: 6vw;
      padding-left: 3vw;
      text-decoration: none;
      transition: 0.25s;
    }
    
    .top-bar__nav-list a:hover {
      color: rgb(91, 196, 221);
    }
    
    .top-bar__nav-list a:focus {
      color: rgb(91, 196, 221);
      outline: none;
    }
    
    @media screen and (max-width: 500px) {
      .top-bar__nav-list {
        align-items: flex-end;
        background: white;
        flex-direction: column;
        height: 100%;
        max-height: 100%;
        overflow: hidden;
        padding-right: 4vw;
        position: fixed;
        transition: all ease-in-out 1s;
        -webkit-transform: translateZ(0);
        -moz-transform: translateZ(0);
        -ms-transform: translateZ(0);
        -o-transform: translateZ(0);
        transform: translateZ(0);
        right: 0;
        width: 100%;
      }
      .top-bar__nav.collapsed .top-bar__nav-list {
        max-height: 0;
      }
      .top-bar__nav-list.collapsed {
        padding-right: 6vw;
      }
      .nav-ul li a {
        color: gray;
      }
      .top-bar__nav-toggle {
        display: inline-block;
        body {
          background: gray;
        }
        .top-bar {
          align-items: center;
          display: flex;
          flex-wrap: wrap;
          margin-right: 2vw;
        }
        .top-bar__nav-toggle {
          background: transparent;
          border: none;
          cursor: pointer;
          display: none;
          font-size: 50px;
          min-width: 5vw;
          text-align: center;
          transition: 0.25s;
        }
        .hamburger {
          height: 4vw;
          position: relative;
        }
        .hamburger span {
          background: white;
          border-radius: 25%;
          height: 2px;
          position: absolute;
          transform: translate(-50%, -50%);
          width: 4vw;
        }
        .hamburger:focus span {
          background: rgb(91, 196, 221);
          outline: none;
        }
        .hamburger:hover span {
          background: rgb(91, 196, 221);
        }
        .hamburger span:nth-child(1) {
          top: 20%;
          transition: top 125ms 250ms, transform 125ms;
        }
        .hamburger span:nth-child(2) {
          top: 50%;
          transition: top 125ms 250ms, transform 125ms;
        }
        .hamburger span:nth-child(3) {
          top: 80%;
          transition: top 125ms 250ms, transform 125ms;
        }
        .hamburger.closed span:nth-child(1) {
          top: 50%;
          transform: translate(-50%, -50%) rotate(45deg);
          transition: top 125ms, transform 125ms 250ms;
        }
        .hamburger.closed span:nth-child(2) {
          top: 50%;
          transform: translate(-50%, -50%) rotate(-45deg);
          transition: top 125ms, transform 125ms 250ms;
        }
        .hamburger.closed span:nth-child(3) {
          top: 50%;
          transform: translate(-50%, -50%) rotate(-45deg);
          transition: top 125ms, transform 125ms 250ms;
        }
        .nav-ul {
          display: flex;
          justify-content: center;
          list-style-type: none;
          padding: 0;
        }
        .top-bar__nav {
          background: transparent;
          max-height: 400px;
          overflow: hidden;
          transition: 0.25s;
          width: 100%;
        }
        .top-bar__nav.collapsed .top-bar__nav-list {
          transition: all ease-in-out 1s;
        }
        .top-bar__nav-list {
          list-style: none;
        }
        .top-bar__nav-list li {
          text-align: center;
        }
        .collapsed .top-bar__nav-list a {
          font-size: 2vw;
        }
        .top-bar__nav-list a {
          border-bottom: 2px solid transparent;
          color: white;
          display: inline-block;
          font-size: 6vw;
          padding-left: 3vw;
          text-decoration: none;
          transition: 0.25s;
        }
        .top-bar__nav-list a:hover {
          color: rgb(91, 196, 221);
        }
        .top-bar__nav-list a:focus {
          color: rgb(91, 196, 221);
          outline: none;
        }
        @media screen and (max-width: 500px) {
          .top-bar__nav-list {
            align-items: flex-end;
            background: white;
            flex-direction: column;
            height: 100%;
            max-height: 100%;
            overflow: hidden;
            padding-right: 4vw;
            position: fixed;
            transition: all ease-in-out 1s;
            -webkit-transform: translateZ(0);
            -moz-transform: translateZ(0);
            -ms-transform: translateZ(0);
            -o-transform: translateZ(0);
            transform: translateZ(0);
            right: 0;
            width: 100%;
          }
          .top-bar__nav.collapsed .top-bar__nav-list {
            max-height: 0;
          }
          .top-bar__nav-list.collapsed {
            padding-right: 6vw;
          }
          .nav-ul li a {
            color: gray;
          }
          .top-bar__nav-toggle {
            display: inline-block;
          }
    <div class="top-bar">
      <button class="top-bar__nav-toggle hamburger" id="top-nav-toggle">
              Close
            </button>
      <nav class="top-bar__nav collapsed" id="top-bar__nav">
        <ul class="top-bar__nav-list nav-ul">
          <li>
            <a class="navlink" href="#">Home</a>
          </li>
          <li>
            <a class="navlink" href="#Portfolio">Work</a>
          </li>
          <li>
            <a class="navlink" href="#About">About</a>
          </li>
          <li>
            <a class="navlink" href="#Contact">Contact</a>
          </li>
        </ul>
      </nav>
    </div>