【问题标题】:How to make dropdown (dropdown content) to show below each button when clicked单击时如何使下拉列表(下拉内容)显示在每个按钮下方
【发布时间】:2022-08-19 01:38:24
【问题描述】:

几天来,我一直在尝试解决这个问题,但只是给了我很多时间来破解我的大脑,却没有得到解决方案。 我要解决的是,当我单击每个按钮时,我希望它的下拉菜单显示在其自己的按钮下方,而不是所有下拉菜单都显示在屏幕左侧,其次,当它显示在其按钮下方时,内容应该改变。

谢谢。

function myFunction() {
  document.getElementById(\"myDropdown\").classList.toggle(\"show\");
}

window.onclick = function(event) {
  if (!event.target.matches(\'.dropbtn\')) {
    let dropdowns = document.getElementsByClassName(\"dropdown-content\");
    let i;
    for (i = 0; i < dropdowns.length; i++) {
      let openDropdown = dropdowns[i];
      if (openDropdown.classList.contains(\'show\')) {
        openDropdown.classList.remove(\'show\');
      }
    }
  }
};
nav {
display: flex;
}

.dropbtn {
  font-size: 12px;    
  border: none;
  outline: none;
  text-align: center;
  color: #f2f2f2;
  width: 155px;
  padding: 14px 16px;
  background-color: inherit;
  font-family: serif;
  text-transform: capitalize;
  border-right: 1px solid gray;
  border-bottom: 1px solid gray;
}

.dropbtn:hover, .dropbtn:focus {
  background-color: #2980B9;
}

.dropdown {
  position: relative;
}

.dropdown-content {
  display: none;
  position: absolute;
  background-color: #f1f1f1;
  min-width: 200px;
  height: 200px;
  overflow: hidden;
  box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
  z-index: 1;
  border-radius: 10px;
  padding-bottom: 20px;
  padding-top: 40px;
  opacity: .9;
}

.dropdown-content a {
  color: blue;
  padding: 12px 20px;
  text-decoration: none;
  display: block;
  width: 100%;
  font-size: 12px;
  background-color: ;
  border-bottom: 1px solid gray;
}

.dropdown a:hover {
  background-color: gray;
}

.show {
  display: block;
}
<nav>                   
    <div class=\"dropdown\">
        <button class=\"dropbtn\" id=\"active\" onclick=\"myFunction()\">new
        </button>
        <div class=\"dropdown-content\" id=\"myDropdown\">
            <a href=\"#\">link 1</a>
            <a href=\"#\">link 2</a>
            <a href=\"#\">link 3</a>
        </div>
    </div> 

    <div class=\"dropdown\">
        <button class=\"dropbtn\" onclick=\"myFunction()\">fresh
        </button>
        <div class=\"dropdown-content\" id=\"myDropdown\">
            <a href=\"#\">link 4</a>
            <a href=\"#\">link 5</a>
            <a href=\"#\">link 6</a>
        </div>
    </div> 

    <div class=\"dropdown\">
        <button class=\"dropbtn\" onclick=\"myFunction()\">naija
        </button>
        <div class=\"dropdown-content\" id=\"myDropdown\">
            <a href=\"#\">link 7</a>
            <a href=\"#\">link 8</a>
            <a href=\"#\">link 9</a>
        </div>
    </div> 
</nav>
  • getElementsByClassName() 返回一个实时的HTMLCollection,其中包含具有指定类名的每个后代元素。 HTMLCollection 即是一个对象。
  • 请改用querySelectorAll(\'.dropdown-content\')

标签: javascript html css


【解决方案1】:

您的代码现在正在做的是创建三个下拉元素。然后,当单击按钮时,您正在执行myFunction(),得到#myDropdown。引用 MDN 文档,元素的 id 是“文档中唯一的”。但是,您有三个具有相同 ID 的元素。因此,当您在 JS 代码的第二行执行 document.getElementById("myDropdown") 时,它会找到第一个例子#myDropdown 并在该元素上切换 show 类。

提供的代码有以下变化:

  1. 删除inline events.更好的做法是在 HTML 中使用 addEventListener 而不是像 onclick 这样的内联事件。
  2. 更好的letconst 用法。

    const dropdowns = Array.from(document.getElementsByClassName("dropdown-content"));
    const dropdownButtons = Array.from(document.getElementsByClassName('dropbtn'));
    
    let currentDropdown = 0;
    let dropdownAmount = 0;
    
    dropdownButtons.forEach(function(dropdownBtn, index) {
      dropdownBtn.addEventListener('click', function(e) {
        e.stopPropagation();
        dropdowns[index].classList.toggle('show');
        currentDropdown = index;
        dropdownAmount++;
        
        if (dropdownAmount > 1) { // closes other dropdowns if more than one is open
          for (let i = 0; i < dropdowns.length; i++) {
            const openDropdown = dropdowns[i];
            if (openDropdown.classList.contains('show') && i !== currentDropdown) {
              openDropdown.classList.remove('show');
            }
          }
          dropdownAmount = 1;
        }
      });
    });
    
    window.addEventListener('click', function(event) {
      for (let i = 0; i < dropdowns.length; i++) {
        const openDropdown = dropdowns[i];
        if (openDropdown.classList.contains('show')) {
          openDropdown.classList.remove('show');
        }
        dropdownAmount = 0;
      }
    });
    nav {
    display: flex;
    }
    
    .dropbtn {
      font-size: 12px;    
      border: none;
      outline: none;
      text-align: center;
      color: #f2f2f2;
      width: 155px;
      padding: 14px 16px;
      background-color: inherit;
      font-family: serif;
      text-transform: capitalize;
      border-right: 1px solid gray;
      border-bottom: 1px solid gray;
    }
    
    .dropbtn:hover, .dropbtn:focus {
      background-color: #2980B9;
    }
    
    .dropdown {
      position: relative;
    }
    
    .dropdown-content {
      display: none;
      position: absolute;
      background-color: #f1f1f1;
      min-width: 200px;
      height: 200px;
      overflow: hidden;
      box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
      z-index: 1;
      border-radius: 10px;
      padding-bottom: 20px;
      padding-top: 40px;
      opacity: .9;
    }
    
    .dropdown-content a {
      color: blue;
      padding: 12px 20px;
      text-decoration: none;
      display: block;
      width: 100%;
      font-size: 12px;
      background-color: ;
      border-bottom: 1px solid gray;
    }
    
    .dropdown a:hover {
      background-color: gray;
    }
    
    .show {
      display: block;
    }
    <nav>                   
        <div class="dropdown">
            <button class="dropbtn" id="active">new</button>
            <div class="dropdown-content">
                <a href="#">link 1</a>
                <a href="#">link 2</a>
                <a href="#">link 3</a>
            </div>
        </div> 
    
        <div class="dropdown">
            <button class="dropbtn">fresh</button>
            <div class="dropdown-content">
                <a href="#">link 4</a>
                <a href="#">link 5</a>
                <a href="#">link 6</a>
            </div>
        </div> 
    
        <div class="dropdown">
            <button class="dropbtn"><i>naija</i></button> <!-- demonstration for op's problem -->
            <div class="dropdown-content">
                <a href="#">link 7</a>
                <a href="#">link 8</a>
                <a href="#">link 9</a>
            </div>
        </div> 
    </nav>

    编辑:修复了代码,以便.dropbtns 的子元素也打开下拉菜单。 .dropbtn click 事件正在工作,但随后它也触发了 window click 事件。 window click 事件检查了不是按钮的事件目标,因此它关闭了所有下拉菜单。现在,如果.dropbtn click 事件被触发,e.stopPropagation 会被调用以防止window click 事件触发。

【讨论】:

  • 非常感谢@bub。您的回答确实有效并且有效。我非常感谢您为此付出的努力,这让我很开心。
  • 我刚刚发现,如果在具有类 dropbtn 的按钮内放置/添加了任何其他按钮或容器,如果单击了此类添加的按钮或容器,则下拉内容不会显示。例如 <div class="dropdown"> <button class="dropbtn">naija <i class="fa fa-caret-down"></i></button> <div class="dropdown-content"> < a href="#">链接 7</a> <a href="#">链接 8</a> <a href="#">链接 9</a> </div> </div>
  • 现在应该解决了。请检查代码,看看它是否有效。谢谢!
猜你喜欢
  • 2017-04-13
  • 2021-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多