单击其他区域(包括其他下拉列表)

时间:2016-10-29 14:11:03

标签: javascript jquery html css drop-down-menu

我正在尝试制作一个下拉菜单,其中 .dropdown-content 在点击 .dropbtn 时显示,如果用户点击其他任何部分,则会消失页面,包括另一个 .dropbtn 。我在此处找到的大多数解决方案都需要检测页面上任何位置的单击并停止 .dropdown 类中的传播。问题是我有.dropdown类的多个按钮,我认为我不需要一个复杂的解决方案。我想我只需要帮助修改现有的javascript。

CSS

<style>
ul.topnav .dropdown {display: inline-block;}
ul.topnav .dropbtn {background-color: black;}
ul.topnav .dropbtn:after {/*inject down caret*/}
ul.topnav .dropbtn.active:after {/*inject up caret*/}
ul.topnav .dropdown-content {display: none;}
ul.topnav .dropdown-content.show {display:block;}
</style>

HTML

<ul class="topnav" id="myTopnav">
    <li><a href="#">Home</a></li>
    <li class="dropdown">
        <a href="#" class="dropbtn">Locations</a>
        <div class="dropdown-content">
            <a href="#">Location 1</a>
            <a href="#">Location 2</a>
        </div>
    </li>
    <li class="dropdown">
        <a href="#" class="dropbtn">Photos</a>
        <div class="dropdown-content">
            <a href="#">Folder 1</a>
            <a href="#">Folder 2</a>
            <a href="#">Folder 3</a>
        </div>
    </li>
    <li><a href="#about">About Us</a></li>
</ul>

JAVASCRIPT

<script>
/*controls topnav accordion*/
var acc = document.getElementsByClassName("dropbtn");
var i;
for (i = 0; i < acc.length; i++) {
    acc[i].onclick = function(){
        this.classList.toggle("active");
        this.nextElementSibling.classList.toggle("show");
    }
}
</script>

这会让 .dropdown-content 在点击其父 .dropbtn 时出现并消失,但我仍然可以一次打开多个下拉菜单,而且没有当我点击另一个或点击页面本身时关闭。我试图编写一段javascript,当我点击任何地方但当前活动的 .dropbtn <时,它会切换 .dropbtn.active .dropdown-content.show / em>,但它不起作用。这是我破碎的尝试:

<script>
window.onclick = function(e) {
    if (!e.target.matches('.dropbtn.active')) {
        this.classList.toggle("active");
        this.nextElementSibling.classList.toggle("show”);
}
</script>

我怀疑有一个简单的修复,但我是javascript的新手。再次,我希望当我单击一个新的下拉按钮时关闭所有打开的下拉菜单,并且当我点击下拉列表外的任何地方时,该下拉菜单将关闭。也许这段代码和上面(工作)的javascript可以合并?请帮忙。

1 个答案:

答案 0 :(得分:0)

尝试此示例使用for循环切换仅点击的元素,并使用.show vs e.target.nextElementSibling

删除其他人的e.target.previousElementSibling课程

&#13;
&#13;
<style>
  ul.topnav .dropdown {
    display: inline-block;
  }
  ul.topnav .dropbtn {
    background-color: black;
  }
  ul.topnav .dropbtn:after {
    /*inject down caret*/
  }
  ul.topnav .dropbtn.active:after {
    /*inject up caret*/
  }
  ul.topnav .dropdown-content {
    display: none;
  }
  ul.topnav .dropdown-content.show {
    display: block;
  }
</style>

<ul class="topnav" id="myTopnav">
  <li><a href="#">Home</a>
  </li>
  <li class="dropdown">
    <a href="#" class="dropbtn">Locations</a>
    <div class="dropdown-content">
      <a href="#">Location 1</a>
      <a href="#">Location 2</a>
    </div>
  </li>
  <li class="dropdown">
    <a href="#" class="dropbtn">Photos</a>
    <div class="dropdown-content">
      <a href="#">Folder 1</a>
      <a href="#">Folder 2</a>
      <a href="#">Folder 3</a>
    </div>
  </li>
  <li><a href="#about">About Us</a>
  </li>
</ul>
<script>
  window.onclick = function(e) {
    var targ = e.target;
    var drp = document.getElementsByClassName("dropdown-content");
    for (var i = 0; i < drp.length; i++) {
      if (drp[i].previousElementSibling == targ) {
        targ.nextElementSibling.classList.toggle("active");
        targ.nextElementSibling.classList.toggle("show");
      } else {
        drp[i].className = drp[i].className.replace(/\bshow\b/, '');
      }
    }

  }
</script>
&#13;
&#13;
&#13;