JavaScript下拉菜单功能出现问题

时间:2019-04-30 06:32:15

标签: javascript html css

我唯一的问题是,当您从一个下拉菜单标题转到下一个菜单下拉标题时,第一个菜单保持打开状态,我已附加了代码笔,希望可以使用。

https://codepen.io/gsxr1000/pen/yrGWEd

编辑:以下解决方案很棒,但是它们都失去了菜单的切换灵活性,这意味着无法通过单击同一菜单项来下拉菜单和备份菜单。这对于菜单功能非常重要,因为在某些小型电话中,下拉菜单可能会占据屏幕的大部分位置,因此它们将无法关闭打开的下拉菜单。

function blockchain() {
  var element = document.getElementById("dropone");
  element.classList.toggle("mystyle");
}

function products() {
  var element = document.getElementById("droptwo");
  element.classList.toggle("mystyle");
}

function payments() {
  var element = document.getElementById("dropthree");
  element.classList.toggle("mystyle");
}

function services() {
  var element = document.getElementById("dropfore");
  element.classList.toggle("mystyle");
}


window.onclick = function(event) {
  if (!event.target.matches('.subnavbtn')) {
    var dropdowns = document.getElementsByClassName("subnav-content");
    var i;
    for (i = 0; i < dropdowns.length; i++) {
      var openDropdown = dropdowns[i];
      if (openDropdown.classList.contains('mystyle')) {
        openDropdown.classList.remove('mystyle');
      }
    }
  }
}
body {
  max-width: 1400px;
  margin: 0 auto;
  padding: 5px;
}

.navbar {
  position: relative;
  max-width: 700px;
  width: 100%;
}

.navbar a {
  float: left;
  font-size: 16px;
  text-align: center;
  padding: 5px 0px;
  text-decoration: none;
  color: black;
}

.navbar a:nth-child(4n+1) {
  border-left: px solid #4caf50;
}

.subnav {
  box-sizing: border-box;
  border-left: 1px solid white;
  float: left;
  width: 25%;
  text-align: center;
  background-color: #4caf50;
}

.subnav:last-child {
  border-right: ;
}

.subnav:first-child {
  border-left: 1px solid #4caf50;
}

.subnav .subnavbtn {
  font-size: 16px;
  width: 100%;
  background-color: #4caf50;
  border: none;
  outline: none;
  color: white;
  padding: 10px 1px;
  margin: 0;
  z-index: 1;
}

.subnav-content {
  position: absolute;
  display: none;
  border: 1px solid #4caf50;
  border-top: none;
  max-width: 700px;
  width: 100%;
  left: 0;
  text-decoration: none;
  background-color: #f4f4f4;
  box-sizing: border-box;
}

.subnav-content a {
  float: left;
  width: 25%;
  box-sizing: border-box;
  border-left: 1px solid white;
  font-size: 12px;
}

.subnav-content a:hover {
  color: white;
}

.subnav-content a:nth-child(4n-3) {
  border-left: none;
}

.navbar a:hover,
.subnav:hover .subnavbtn {
  font-weight: bold;
  background-color: #2c602e;
}

.mystyle {
  display: block;
}

.subnav:hover .subnav-content {
  box-sizing: border-box;
}

@media only screen and (max-width: 500px) {
  .subnav-content a {
    width: 50%;
  }
  .subnav .subnavbtn {
    font-size: 14px;
  }
  .subnav-content a:nth-child(2n-1) {
    border-left: none;
  }
}
<div class="navbar">
  <div class="subnav">
    <button class="subnavbtn" onclick="blockchain()">Blockchain</button>
    <div class="subnav-content" class="drop1" id="dropone">
      <a href="#company">Company</a>
      <a href="#team">Team</a>
      <a href="#careers">Careers</a>
    </div>
  </div>
  <div class="subnav">
    <button class="subnavbtn" onclick="products()">Products</button>
    <div class="subnav-content" class="drop2" id="droptwo">
      <a href="#bring">Bring</a>
      <a href="#deliver">Deliver</a>
      <a href="#package">Package</a>
      <a href="#express">Express</a>
      <a href="#bring">Bring</a>
      <a href="#deliver">Deliver</a>
      <a href="#package">Package</a>
      <a href="#bring">Bring</a>
      <a href="#deliver">Deliver</a>
      <a href="#package">Package</a>
      <a href="#express">Express</a>
      <a href="#bring">Bring</a>
      <a href="#deliver">Deliver</a>
      <a href="#package">Package</a>
    </div>
  </div>
  <div class="subnav">
    <button class="subnavbtn" onclick="payments()">Payments</button>
    <div class="subnav-content" class="drop3" id="dropthree">
      <a href="#link1">Link 1</a>
      <a href="#link2">Link 2</a>
      <a href="#link3">Link 3</a>
      <a href="#link4">Link 4</a>
    </div>
  </div>
  <div class="subnav">
    <button class="subnavbtn" onclick="services()">Services</button>
    <div class="subnav-content" class="drop4" id="dropfore">
      <a href="#bring">Bring</a>
      <a href="#deliver">Deliver</a>
      <a href="#package">Package</a>
      <a href="#express">Express</a>
    </div>
  </div>
</div>

2 个答案:

答案 0 :(得分:0)

  1. 创建一个函数以关闭所有导航项;
  2. 单击导航项或单击文档时调用此功能。

function blockchain() {
  var element = document.getElementById("dropone");
  if (element.classList.contains("mystyle")) {
    element.classList.remove("mystyle");
  } else {
    closeAll();
    element.classList.add("mystyle");
  }
}
function products() {
  var element = document.getElementById("droptwo");
  if (element.classList.contains("mystyle")) {
    element.classList.remove("mystyle");
  } else {
    closeAll();
    element.classList.add("mystyle");
  }
}
function payments() {
  var element = document.getElementById("dropthree");
  if (element.classList.contains("mystyle")) {
    element.classList.remove("mystyle");
  } else {
    closeAll();
    element.classList.add("mystyle");
  }
}
function services() {
  var element = document.getElementById("dropfore");
  if (element.classList.contains("mystyle")) {
    element.classList.remove("mystyle");
  } else {
    closeAll();
    element.classList.add("mystyle");
  }
}

window.onclick = function(event) {
  closeAll(event);
}

function closeAll(event = null) {
  if (!event || !event.target.matches('.subnavbtn')) {
    var dropdowns = document.getElementsByClassName("subnav-content");
    var i;
    for (i = 0; i < dropdowns.length; i++) {
      var openDropdown = dropdowns[i];
      if (openDropdown.classList.contains('mystyle')) {
        openDropdown.classList.remove('mystyle');
      }
    }
  }
}
body {
  max-width: 1400px;
  margin: 0 auto;
  padding: 5px;
}


.navbar{
  position: relative;
  max-width: 700px;
  width: 100%;
}

.navbar a {
  float: left;
  font-size: 16px;
  text-align: center;
  padding: 5px 0px;
  text-decoration: none;
  color: black;
}

.navbar a:nth-child(4n+1) {
  border-left: px solid #4caf50;
}

.subnav {
  box-sizing: border-box;
  border-left: 1px solid white;
  float: left;
  width: 25%;
  text-align: center;
  background-color: #4caf50;
}

.subnav:last-child {
  border-right: ;
}

.subnav:first-child {
  border-left: 1px solid #4caf50;
}

.subnav .subnavbtn {
  font-size: 16px;
  width: 100%;
  background-color: #4caf50;
  border: none;
  outline: none;
  color: white;
  padding: 10px 1px;
  margin: 0;
  z-index: 1;
}

.subnav-content {
  position: absolute;
  display: none;
  border: 1px solid #4caf50;
  border-top: none;
  max-width: 700px;
  width: 100%;
  left: 0;
  text-decoration: none;
  background-color: #f4f4f4;
  box-sizing: border-box;
}


.subnav-content a {
  float: left;
  width: 25%;
  box-sizing: border-box;
  border-left: 1px solid white;
  font-size: 12px;
}

.subnav-content a:hover {
  color:white;
}

.subnav-content a:nth-child(4n-3) {
  border-left: none;
}

.navbar a:hover, .subnav:hover .subnavbtn {
  font-weight: bold;
  background-color: #2c602e;
}

.mystyle {
  display:block;
}

.subnav:hover .subnav-content{
  box-sizing: border-box;
}
@media only screen and (max-width: 500px) {
  .subnav-content a {
    width: 50%;
  }
  .subnav .subnavbtn {
    font-size: 14px;
  }
  .subnav-content a:nth-child(2n-1) {
  border-left: none;
  }
}
<div class="navbar">
    <div class="subnav">
      <button class="subnavbtn" onclick="blockchain()">Blockchain</button>
      <div class="subnav-content" class="drop1" id="dropone">
        <a href="#company">Company</a>
        <a href="#team">Team</a>
        <a href="#careers">Careers</a>
      </div>
    </div>
    <div class="subnav">
      <button class="subnavbtn" onclick="products()">Products</button>
      <div class="subnav-content" class="drop2" id="droptwo">
        <a href="#bring">Bring</a>
        <a href="#deliver">Deliver</a>
        <a href="#package">Package</a>
        <a href="#express">Express</a>
        <a href="#bring">Bring</a>
        <a href="#deliver">Deliver</a>
        <a href="#package">Package</a>
        <a href="#bring">Bring</a>
        <a href="#deliver">Deliver</a>
        <a href="#package">Package</a>
        <a href="#express">Express</a>
        <a href="#bring">Bring</a>
        <a href="#deliver">Deliver</a>
        <a href="#package">Package</a>
      </div>
    </div>
    <div class="subnav">
      <button class="subnavbtn" onclick="payments()">Payments</button>
      <div class="subnav-content" class="drop3" id="dropthree">
        <a href="#link1">Link 1</a>
        <a href="#link2">Link 2</a>
        <a href="#link3">Link 3</a>
        <a href="#link4">Link 4</a>
      </div>
    </div>
    <div class="subnav">
      <button class="subnavbtn" onclick="services()">Services</button>
      <div class="subnav-content" class="drop4" id="dropfore">
        <a href="#bring">Bring</a>
        <a href="#deliver">Deliver</a>
        <a href="#package">Package</a>
        <a href="#express">Express</a>
      </div>
    </div>
  </div>

更简单地使用jQuery进行练习:

$('.subnav').on('click', function() {
  $('.subnav').not(this).find('.subnav-content').removeClass('mystyle');
  $(this).find('.subnav-content').toggleClass('mystyle');
});

$(document).on('click', function(e) {
  if (!$(e.target).hasClass('subnavbtn')) {
    $('.subnav-content').removeClass('mystyle');
  }
});
body {
  max-width: 1400px;
  margin: 0 auto;
  padding: 5px;
}


.navbar{
  position: relative;
  max-width: 700px;
  width: 100%;
}

.navbar a {
  float: left;
  font-size: 16px;
  text-align: center;
  padding: 5px 0px;
  text-decoration: none;
  color: black;
}

.navbar a:nth-child(4n+1) {
  border-left: px solid #4caf50;
}

.subnav {
  box-sizing: border-box;
  border-left: 1px solid white;
  float: left;
  width: 25%;
  text-align: center;
  background-color: #4caf50;
}

.subnav:last-child {
  border-right: ;
}

.subnav:first-child {
  border-left: 1px solid #4caf50;
}

.subnav .subnavbtn {
  font-size: 16px;
  width: 100%;
  background-color: #4caf50;
  border: none;
  outline: none;
  color: white;
  padding: 10px 1px;
  margin: 0;
  z-index: 1;
}

.subnav-content {
  position: absolute;
  display: none;
  border: 1px solid #4caf50;
  border-top: none;
  max-width: 700px;
  width: 100%;
  left: 0;
  text-decoration: none;
  background-color: #f4f4f4;
  box-sizing: border-box;
}


.subnav-content a {
  float: left;
  width: 25%;
  box-sizing: border-box;
  border-left: 1px solid white;
  font-size: 12px;
}

.subnav-content a:hover {
  color:white;
}

.subnav-content a:nth-child(4n-3) {
  border-left: none;
}

.navbar a:hover, .subnav:hover .subnavbtn {
  font-weight: bold;
  background-color: #2c602e;
}

.mystyle {
  display:block;
}

.subnav:hover .subnav-content{
  box-sizing: border-box;
}
@media only screen and (max-width: 500px) {
  .subnav-content a {
    width: 50%;
  }
  .subnav .subnavbtn {
    font-size: 14px;
  }
  .subnav-content a:nth-child(2n-1) {
  border-left: none;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="navbar">
    <div class="subnav">
      <button class="subnavbtn">Blockchain</button>
      <div class="subnav-content" class="drop1" id="dropone">
        <a href="#company">Company</a>
        <a href="#team">Team</a>
        <a href="#careers">Careers</a>
      </div>
    </div>
    <div class="subnav">
      <button class="subnavbtn">Products</button>
      <div class="subnav-content" class="drop2" id="droptwo">
        <a href="#bring">Bring</a>
        <a href="#deliver">Deliver</a>
        <a href="#package">Package</a>
        <a href="#express">Express</a>
        <a href="#bring">Bring</a>
        <a href="#deliver">Deliver</a>
        <a href="#package">Package</a>
        <a href="#bring">Bring</a>
        <a href="#deliver">Deliver</a>
        <a href="#package">Package</a>
        <a href="#express">Express</a>
        <a href="#bring">Bring</a>
        <a href="#deliver">Deliver</a>
        <a href="#package">Package</a>
      </div>
    </div>
    <div class="subnav">
      <button class="subnavbtn">Payments</button>
      <div class="subnav-content" class="drop3" id="dropthree">
        <a href="#link1">Link 1</a>
        <a href="#link2">Link 2</a>
        <a href="#link3">Link 3</a>
        <a href="#link4">Link 4</a>
      </div>
    </div>
    <div class="subnav">
      <button class="subnavbtn">Services</button>
      <div class="subnav-content" class="drop4" id="dropfore">
        <a href="#bring">Bring</a>
        <a href="#deliver">Deliver</a>
        <a href="#package">Package</a>
        <a href="#express">Express</a>
      </div>
    </div>
  </div>

答案 1 :(得分:0)

仅使用css的解决方案会使问题更容易解决。

如果:focus选择器是最后一个被单击的元素,则会选择该元素。

:focus-within会执行相同的操作,但如果有孩子有焦点,也会执行此操作。

+选择下一个同级,在您的情况下为具有.subnav-content的div

/*
 * When the button is focused this makes it click-through.
 * This hast the efect that when the user clicks the button again the click event
 * goes through the button and 'hits' the element behind it and so the button looses focus.
 */
.subnavbtn:focus, .subnavbtn:focus-within {
  pointer-events: none;
}

.subnavbtn:focus + .subnav-content, .subnavbtn:focus-within + .subnav-content {
  display: block;
}



body {
  max-width: 1400px;
  margin: 0 auto;
  padding: 5px;
}


.navbar{
  position: relative;
  max-width: 700px;
  width: 100%;
}

.navbar a {
  float: left;
  font-size: 16px;
  text-align: center;
  padding: 5px 0px;
  text-decoration: none;
  color: black;
}

.navbar a:nth-child(4n+1) {
  border-left: px solid #4caf50;
}

.subnav {
  box-sizing: border-box;
  border-left: 1px solid white;
  float: left;
  width: 25%;
  text-align: center;
  background-color: #4caf50;
}

.subnav:last-child {
  border-right: ;
}

.subnav:first-child {
  border-left: 1px solid #4caf50;
}

.subnav .subnavbtn {
  font-size: 16px;
  width: 100%;
  background-color: #4caf50;
  border: none;
  outline: none;
  color: white;
  padding: 10px 1px;
  margin: 0;
  z-index: 1;
}

.subnav-content {
  position: absolute;
  display: none;
  border: 1px solid #4caf50;
  border-top: none;
  max-width: 700px;
  width: 100%;
  left: 0;
  text-decoration: none;
  background-color: #f4f4f4;
  box-sizing: border-box;
}


.subnav-content a {
  float: left;
  width: 25%;
  box-sizing: border-box;
  border-left: 1px solid white;
  font-size: 12px;
}

.subnav-content a:hover {
  color:white;
}

.subnav-content a:nth-child(4n-3) {
  border-left: none;
}

.navbar a:hover, .subnav:hover .subnavbtn {
  font-weight: bold;
  background-color: #2c602e;
}

.subnav:hover .subnav-content{
  box-sizing: border-box;
}
@media only screen and (max-width: 500px) {
  .subnav-content a {
    width: 50%;
  }
  .subnav .subnavbtn {
    font-size: 14px;
  }
  .subnav-content a:nth-child(2n-1) {
  border-left: none;
  }
}
<div class="navbar">
    <div class="subnav">
      <button class="subnavbtn">Blockchain</button>
      <div class="subnav-content" class="drop1" id="dropone">
        <a href="#company">Company</a>
        <a href="#team">Team</a>
        <a href="#careers">Careers</a>
      </div>
    </div>
    <div class="subnav">
      <button class="subnavbtn">Products</button>
      <div class="subnav-content" class="drop2" id="droptwo">
        <a href="#bring">Bring</a>
        <a href="#deliver">Deliver</a>
        <a href="#package">Package</a>
        <a href="#express">Express</a>
        <a href="#bring">Bring</a>
        <a href="#deliver">Deliver</a>
        <a href="#package">Package</a>
        <a href="#bring">Bring</a>
        <a href="#deliver">Deliver</a>
        <a href="#package">Package</a>
        <a href="#express">Express</a>
        <a href="#bring">Bring</a>
        <a href="#deliver">Deliver</a>
        <a href="#package">Package</a>
      </div>
    </div>
    <div class="subnav">
      <button class="subnavbtn">Payments</button>
      <div class="subnav-content" class="drop3" id="dropthree">
        <a href="#link1">Link 1</a>
        <a href="#link2">Link 2</a>
        <a href="#link3">Link 3</a>
        <a href="#link4">Link 4</a>
      </div>
    </div>
    <div class="subnav">
      <button class="subnavbtn">Services</button>
      <div class="subnav-content" class="drop4" id="dropfore">
        <a href="#bring">Bring</a>
        <a href="#deliver">Deliver</a>
        <a href="#package">Package</a>
        <a href="#express">Express</a>
      </div>
    </div>
  </div>