javascript - 单击带有 Vanilla JS 的菜单链接时如何隐藏下拉菜单?

标签 javascript responsive

我有这个漂亮的菜单,并在单击菜单内的链接时试图关闭菜单。但是对于 querySelectorAll 我得到了一个错误 navLinks.addEventListener is not a function。

当我使用 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>

最佳答案

您可以将链接变量 link.addEventListener('click', () => { ... }) 上的事件添加到 querySelectorAll('.nav-链接 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>

关于javascript - 单击带有 Vanilla JS 的菜单链接时如何隐藏下拉菜单?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55165303/

相关文章:

javascript - 将 $scope 添加到 Controller

javascript - 如何按对象的值对对象数组进行排序

java - Bootstrap 下拉菜单不起作用

javascript - Cesiumjs 缩放到鼠标

html - 当我们使用 flex 调整窗口大小时,自动调整具有适当间隙和宽度的 div

css - 在小屏幕上响应时,粘性下拉导航栏消失

javascript - 使用 interact.js 的拖放功能

jquery - 动画响应式 Svg-Map

php - 创建自定义模板 Wordpress - 无响应

css - 2 使用 Bootstrap 4 的列响应式布局