当使用Vanilla JS单击菜单链接时,如何隐藏下拉菜单?

时间:2019-03-14 14:39:14

标签: javascript responsive

我有这个不错的菜单,并在单击菜单内的链接时尝试关闭菜单。但是使用querySelectorAll时出现错误navLinks.addEventListener不是函数。

当我使用querySelector时,只有第一个链接正在响应。

我可以给每个链接另一个类,并使其具有5个相同的功能,但是我想使用DRY代码。 正确的方法是什么?

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


  burger.addEventListener('click', () => {  
    // Toggle Nav
    nav.classList.toggle('nav-active');
     // animate navlinks
    navLinks.forEach((link, index) => {
      if(link.style.animation) {
        link.style.animation = ''
      } else {
        link.style.animation = `navLinkFade 0.5s ease forwards ${index / 7 +0.5}s`; 
     }
    });
    // burger animation
    burger.classList.toggle('toggle');

    });
}

navSlide();
* {
  margin: 0px;
  padding: 0px;
  -webkit-box-sizing: border-box;
          box-sizing: border-box;
}

nav {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -ms-flex-pack: distribute;
      justify-content: space-around;
  -webkit-box-align: center;
      -ms-flex-align: center;
          align-items: center;
  min-height: 8vh;
  background-color: #5e4954;
  font-family: 'Poppins', sans-serif;
}

nav .logo {
  color: #e2e2e2;
  letter-spacing: 5px;
  font-size: 20px;
}

nav .nav-links {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -ms-flex-pack: distribute;
      justify-content: space-around;
  width: 30%;
}

nav .nav-links li {
  list-style: none;
}

nav .nav-links li a {
  color: white;
  text-decoration: none;
  letter-spacing: 3px;
  font-weight: bold;
  font-size: 0.8rem;
}

nav .burger {
  display: none;
}

nav .burger div {
  width: 25px;
  height: 3px;
  background-color: #e2e2e2;
  margin: 5px;
  -webkit-transition: all 0.3s ease;
  transition: all 0.3s ease;
}

@media screen and (max-width: 1024px) {
  .nav-links {
    width: 60% !important;
  }
}

@media screen and (max-width: 768px) {
  body {
    overflow-x: hidden;
  }
  body .nav-links {
    position: absolute;
    right: 0px;
    height: 92vh;
    top: 8vh;
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -webkit-box-orient: vertical;
    -webkit-box-direction: normal;
        -ms-flex-direction: column;
            flex-direction: column;
    -webkit-box-align: center;
        -ms-flex-align: center;
            align-items: center;
    background-color: #5e4954;
    width: 100% !important;
    -webkit-transform: translateX(100%);
            transform: translateX(100%);
    -webkit-transition: -webkit-transform 0.5s ease-in;
    transition: -webkit-transform 0.5s ease-in;
    transition: transform 0.5s ease-in;
    transition: transform 0.5s ease-in, -webkit-transform 0.5s ease-in;
  }
  body .nav-links li {
    opacity: 0;
  }
  body .burger {
    display: block;
    cursor: pointer;
  }
}

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

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

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

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

.toggle .line2 {
  opacity: 0;
}

.toggle .line3 {
  -webkit-transform: rotate(45deg) translate(-5px, -6px);
          transform: rotate(45deg) translate(-5px, -6px);
}
/*# sourceMappingURL=style.css.map */
      <!DOCTYPE html>
      <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <link href="https://fonts.googleapis.com/css?family=Poppins" rel="stylesheet">
        <link rel="stylesheet" href="css/style.css">
        <title>responsive navbar</title>
      </head>
      <body>
        <nav>
          <div class="logo">
            <h4>THE NAV</h4>
          </div><!-- /logo-->
            <ul class="nav-links">
              <li ><a href="#">Home</a></li>
              <li><a href="#">About</a></li>
              <li><a href="#">Projects</a></li>
              <li><a href="#">Contact</a></li>
            </ul>
          <!-- mobile version-->
          <div class="burger">
            <div class ="line1"></div>
            <div class ="line2"></div>
            <div class ="line3"></div>
          </div><!-- /burger-->
        </nav>
      </body>
      <script src="app.js"></script>
      </html>

3 个答案:

答案 0 :(得分:4)

您可以将链接变量link.addEventListener('click', () => { ... })上的事件添加到querySelectorAll('.nav-links li')上的循环中

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

  navLinks.forEach((link, index) => {
    link.addEventListener('click', (e) => {
      e.preventDefault();
      burger.classList.toggle('toggle');
      nav.classList.toggle('nav-active');
      navLinks.forEach(setStyleLink)
    })
  });

  burger.addEventListener('click', () => {
    // Toggle Nav
    nav.classList.toggle('nav-active');
    // animate navlinks
    navLinks.forEach(setStyleLink);
    // burger animation
    burger.classList.toggle('toggle');
  });
}

function setStyleLink(el, index) {
  if (el.style.animation) {
    el.style.animation = ''
  } else {
    el.style.animation = `navLinkFade 0.5s ease forwards ${index / 7 +0.5}s`;
  }
}
navSlide();
* {
  margin: 0px;
  padding: 0px;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
}

nav {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -ms-flex-pack: distribute;
  justify-content: space-around;
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center;
  min-height: 8vh;
  background-color: #5e4954;
  font-family: 'Poppins', sans-serif;
}

nav .logo {
  color: #e2e2e2;
  letter-spacing: 5px;
  font-size: 20px;
}

nav .nav-links {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -ms-flex-pack: distribute;
  justify-content: space-around;
  width: 30%;
}

nav .nav-links li {
  list-style: none;
}

nav .nav-links li a {
  color: white;
  text-decoration: none;
  letter-spacing: 3px;
  font-weight: bold;
  font-size: 0.8rem;
}

nav .burger {
  display: none;
}

nav .burger div {
  width: 25px;
  height: 3px;
  background-color: #e2e2e2;
  margin: 5px;
  -webkit-transition: all 0.3s ease;
  transition: all 0.3s ease;
}

@media screen and (max-width: 1024px) {
  .nav-links {
    width: 60% !important;
  }
}

@media screen and (max-width: 768px) {
  body {
    overflow-x: hidden;
  }
  body .nav-links {
    position: absolute;
    right: 0px;
    height: 92vh;
    top: 8vh;
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -webkit-box-orient: vertical;
    -webkit-box-direction: normal;
    -ms-flex-direction: column;
    flex-direction: column;
    -webkit-box-align: center;
    -ms-flex-align: center;
    align-items: center;
    background-color: #5e4954;
    width: 100% !important;
    -webkit-transform: translateX(100%);
    transform: translateX(100%);
    -webkit-transition: -webkit-transform 0.5s ease-in;
    transition: -webkit-transform 0.5s ease-in;
    transition: transform 0.5s ease-in;
    transition: transform 0.5s ease-in, -webkit-transform 0.5s ease-in;
  }
  body .nav-links li {
    opacity: 0;
  }
  body .burger {
    display: block;
    cursor: pointer;
  }
}

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

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

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

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

.toggle .line2 {
  opacity: 0;
}

.toggle .line3 {
  -webkit-transform: rotate(45deg) translate(-5px, -6px);
  transform: rotate(45deg) translate(-5px, -6px);
}


/*# sourceMappingURL=style.css.map */
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link href="https://fonts.googleapis.com/css?family=Poppins" rel="stylesheet">
  <link rel="stylesheet" href="css/style.css">
  <title>responsive navbar</title>
</head>

<body>
  <nav>
    <div class="logo">
      <h4>THE NAV</h4>
    </div>
    <!-- /logo-->
    <ul class="nav-links">
      <li><a href="#">Home</a></li>
      <li><a href="#">About</a></li>
      <li><a href="#">Projects</a></li>
      <li><a href="#">Contact</a></li>
    </ul>
    <!-- mobile version-->
    <div class="burger">
      <div class="line1"></div>
      <div class="line2"></div>
      <div class="line3"></div>
    </div>
    <!-- /burger-->
  </nav>
</body>
<script src="app.js"></script>

</html>

答案 1 :(得分:1)

在文档上设置侦听器,但仅在单击nav-link-class中的锚标记时才执行操作。

document.addEventListener("click", (e) => {
  const target = e.target;
  if (target.closest(".nav-links a") {
    //do domething
  }
});

答案 2 :(得分:0)

<script>
const navigation = document.querySelector('.navigation');
document.querySelector('.toggle').onclick = function() {
  this.classList.toggle('active');
  navigation.classList.toggle('active');
}
</script>