【问题标题】:How to show dropdown menu when clicked单击时如何显示下拉菜单
【发布时间】:2021-08-26 04:24:22
【问题描述】:

js

const navItems = document.querySelectorAll('.navbar__items')
const dropDown = document.querySelectorAll('.dropdown')

dropDown.forEach(element => {
 element.addEventListener('click',()=>{
     {
         navItems.forEach(nav =>{
             nav.classList.toggle('drop')
         })
     }
         
 })
})

HTML

   <ul class="navbar">
  <li class="nav-menu">
    <div class="dropdown">click</div>
    <ul class="navbar__items">
      <li><a href="#">clicked</a></li>
      <li><a href="#">clicked</a></li>
      <li><a href="#">clicked</a></li>
    </ul>
  </li>
  <li class="nav-menu">
    <div class="dropdown">click</div>
    <ul class="navbar__items">
      <li><a href="#">clicked</a></li>
      <li><a href="#">clicked</a></li>
      <li><a href="#">clicked</a></li>
    </ul>
  </li>
  <li class="nav-menu">
    <div class="dropdown">click</div>
    <ul class="navbar__items">
      <li><a href="#">clicked</a></li>
      <li><a href="#">clicked</a></li>
      <li><a href="#">clicked</a></li>
    </ul>
  </li>
</ul>

CSS

   .navbar{
  position: relative;
}

.navbar__items{
  position: absolute;
  display: none;
}

.drop{ 
  display: block;
}

我有一个导航栏,每个导航栏项目都有下拉项目。当我单击“下拉”类时,我想显示这些下拉项。但问题是当我点击其中一个时,所有下拉菜单都是可见的。如何只显示我点击的列表?

【问题讨论】:

    标签: javascript html css navbar


    【解决方案1】:

    输入以下代码

    <!DOCTYPE html>
    <html>
    <head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
    .dropbtn {
      background-color: #3498DB;
      color: white;
      padding: 16px;
      font-size: 16px;
      border: none;
      cursor: pointer;
    }
    
    .dropbtn:hover, .dropbtn:focus {
      background-color: #2980B9;
    }
    
    .dropdown {
      position: relative;
      display: inline-block;
    }
    
    .dropdown-content {
      display: none;
      position: absolute;
      background-color: #f1f1f1;
      min-width: 160px;
      overflow: auto;
      box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
      z-index: 1;
    }
    
    .dropdown-content a {
      color: black;
      padding: 12px 16px;
      text-decoration: none;
      display: block;
    }
    
    .dropdown a:hover {background-color: #ddd;}
    
    .show {display: block;}
    </style>
    </head>
    <body>
    
    
    
    <div class="dropdown">
      <button onclick="myFunction()" class="dropbtn">Click</button>
      <div id="myDropdown" class="dropdown-content">
        <a href="#home">Clicked</a>
        <a href="#about">Clicked</a>
        <a href="#contact">Clicked</a>
      </div>
    </div>
    
    <script>
    function myFunction() {
      document.getElementById("myDropdown").classList.toggle("show");
    }
    
    window.onclick = function(event) {
      if (!event.target.matches('.dropbtn')) {
        var dropdowns = document.getElementsByClassName("dropdown-content");
        var i;
        for (i = 0; i < dropdowns.length; i++) {
          var openDropdown = dropdowns[i];
          if (openDropdown.classList.contains('show')) {
            openDropdown.classList.remove('show');
          }
        }
      }
    }
    </script>
    
    </body>
    </html>

    【讨论】:

      【解决方案2】:

      如 cmets 中所述,最好使用Event Delegation 技术。

      算法很简单:

      1. 在父元素上添加监听器
      2. 点击时检查下拉菜单是否被点击
      3. 获取我需要打开的下拉菜单
      4. 关闭其他下拉菜单
      5. 从 3 打开下拉菜单。

      const allDropdowns = document.querySelectorAll('.navbar__items')
      const DROP_CLASS = 'drop';
      const navbar = document.querySelector('.navbar');
      
      
      navbar.addEventListener('click', ({target}) => {
          if (!target.classList.contains('dropdown')) return;
        
        const parent = target.parentNode;
        const navItems = parent
          .querySelector('.navbar__items');
      
        allDropdowns.forEach(el => el !== navItems && el.classList.remove(DROP_CLASS));
        
        if (navItems) {
          navItems.classList.toggle(DROP_CLASS);  
        }
      });
      .navbar{
        position: relative;
      }
      
      .navbar__items{
        position: absolute;
        left: 80px;
        display: none;
      }
      
      .drop{ 
        display: block;
      }
         <ul class="navbar">
        <li class="nav-menu">
          <div class="dropdown">click</div>
          <ul class="navbar__items">
            <li><a href="#">clicked</a></li>
            <li><a href="#">clicked</a></li>
            <li><a href="#">clicked</a></li>
          </ul>
        </li>
        <li class="nav-menu">
          <div class="dropdown">click</div>
          <ul class="navbar__items">
            <li><a href="#">clicked</a></li>
            <li><a href="#">clicked</a></li>
            <li><a href="#">clicked</a></li>
          </ul>
        </li>
        <li class="nav-menu">
          <div class="dropdown">click</div>
          <ul class="navbar__items">
            <li><a href="#">clicked</a></li>
            <li><a href="#">clicked</a></li>
            <li><a href="#">clicked</a></li>
          </ul>
        </li>
        </ul>

      【讨论】:

        【解决方案3】:

        使用事件目标获取 parentNode,然后使用 parentNode 查询隐藏元素,因为所有元素都分组在同一个父/子分组中。您还可以在每个元素中为隐藏设置一个初始类 display: none; 并在单击时添加它。 forEach 循环使用点击时的隐藏类将每个元素显示为无。

        const navItems = document.querySelectorAll('.navbar__items')
        const dropDown =  document.querySelectorAll('.dropdown') 
        
        // callback function that passes in the event => e from your listener
        function showDropdown (e){
          // set each navbar__items element display: none using hidden class
          navItems.forEach(el => el.classList.add('hidden'))
          // query the specific .navbar__items in the event.targets group 
          let dd = e.target.parentNode.querySelector('.navbar__items') 
          // remove the hidden class a nd show the dropdown for this event.target
          dd.classList.remove('hidden')  
        }
        
        // iterate over the dropdown element 
        dropDown.forEach(element => {
          // function showDropdown on click
          element.addEventListener('click', showDropdown)
        })
        .navbar {
          position: relative;
        }
        
        .navbar__items {
          position: absolute;
          left: 75px;
        }
        
        .hidden {  
          display: none;
        }
        <ul class="navbar">
          <li class="nav-menu">
            <div class="dropdown">click</div>
            <ul class="navbar__items hidden">
              <li><a href="#">clicked 1</a></li>
              <li><a href="#">clicked 1</a></li>
              <li><a href="#">clicked 1</a></li>
            </ul>
          </li>
          <li class="nav-menu">
            <div class="dropdown">click</div>
            <ul class="navbar__items hidden">
              <li><a href="#">clicked 2</a></li>
              <li><a href="#">clicked 2</a></li>
              <li><a href="#">clicked 2</a></li>
            </ul>
          </li>
          <li class="nav-menu">
            <div class="dropdown">click</div>
            <ul class="navbar__items hidden">
              <li><a href="#">clicked 3</a></li>
              <li><a href="#">clicked 3</a></li>
              <li><a href="#">clicked 3</a></li>
            </ul>
          </li>
        </ul>

        【讨论】:

          【解决方案4】:

          而不是使用 addEventlistener 您应该将 html 中的 onclick 方法添加到具有相同方法名称的每个下拉列表中,但更改每个下拉列表的 ul 类名称,然后在方法中传递类名称,然后使用切换下拉列表参数类名。

          例如,

           function onClick(item) {
              if (document.getElementsByClassName(item).classList.contains('hidden')) {
                  document.getElementsByClassName('dropdown').classList.remove('hidden');
              }
              if (!document.getElementsByClassName(item)[0].classList.contains('hidden')) {
                  document.getElementsByClassName('dropdown').classList.add('hidden');
              }
          }
          <ul class="navbar">
              <li class="nav-menu">
                  <div class="dropdown" onclick="onClick('navbar_items1')">click</div>
                  <ul class="navbar__items1 hidden">
                      <li><a href="#">clicked</a></li>
                      <li><a href="#">clicked</a></li>
                      <li><a href="#">clicked</a></li>
                  </ul>
              </li>
              <li class="nav-menu">
                  <div class="dropdown" onclick="onClick('navbar_items2')">click</div>
                  <ul class="navbar__items2 hidden">
                      <li><a href="#">clicked</a></li>
                      <li><a href="#">clicked</a></li>
                      <li><a href="#">clicked</a></li>
                  </ul>
              </li>
              <li class="nav-menu">
                  <div class="dropdown" onclick="onClick('navbar_items3')">click</div>
                  <ul class="navbar__items3 hidden">
                      <li><a href="#">clicked</a></li>
                      <li><a href="#">clicked</a></li>
                      <li><a href="#">clicked</a></li>
                  </ul>
              </li>
          </ul>

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-12-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多