微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

当使用Javascript无jQuery单击另一个菜单项的按钮第一个“表妹”时,关闭一个菜单项的子菜单

如何解决当使用Javascript无jQuery单击另一个菜单项的按钮第一个“表妹”时,关闭一个菜单项的子菜单

我有一个纯HTML,css(没有Bootstrap),香草javascript和没有jQuery的可单击/可敲击菜单(它可以具有无限级)。

当我单击链接到带有子菜单菜单项的按钮时,它会打开子菜单,而当我再次单击该按钮时,它会关闭菜单。一切都很好。

但是,我无法确定的是,当我单击另一个顶级主项的按钮(我将其称为元素的“表亲”:元素的父级兄弟姐妹的孩子)时,如何关闭已经打开的子菜单打开其子菜单。因此,我最终获得了两个或更多个并排且重叠的子菜单

在这里尝试了一个答案版本:Stackoverflow.com question 41202059,它似乎与我尝试做的最接近,但是没有成功。

这是我的摘录:

/// this script opens the sub-menu when the li button is clicked
document.getElementById("menucontent").addEventListener("click",openSubMenu);
function openSubMenu(event){
    if(event.target.type === "button"){
    event.target.nextElementSibling.classList.toggle("hidden");
    event.target.classList.add("clicked");
    event.target.classList.remove("not-clicked");
    }
}
// this script switches the triangle direction when the button is clicked
document.getElementById("menucontent").addEventListener("click",triangle);
function triangle(event){
    if(event.target.type === "button"){
    event.target.classList.toggle("triangle");
    }
}
// this script closes the submenus when clicking anywhere outside the menu and reverts the triangle to pointing down
document.getElementById("mainbody").addEventListener("click",closeMenu);
function closeMenu(event) {
    if(event.target.type != "button") {
    var level1 = document.getElementsByClassName("level-1");
    var level2 = document.getElementsByClassName("level-2");
    var btnlevel1 = document.getElementsByClassName("btn-level-1");
    var btnlevel2 = document.getElementsByClassName("btn-level-2");
        for (var i = 0; i < level1.length; i++) {
        level1[i].classList.add("hidden"); }
        for (var i = 0; i < level2.length; i++) {
        level2[i].classList.add("hidden"); }
        for (var i = 0; i < btnlevel1.length; i++){
        btnlevel1[i].classList.remove("triangle");
        btnlevel1[i].classList.remove("clicked");}
        for (var i = 0; i < btnlevel2.length; i++) {
        btnlevel2[i].classList.remove("triangle");
        btnlevel2[i].classList.remove("clicked");}
    }
}
document.getElementById("mainbody").addEventListener("click",addClass);
function addClass(event) {
// the click is triggered outside the menu
    if(event.target.type != 'button') {
// these are top level buttons only
    var buttons = document.querySelectorAll('.btn-level-1.clicked');
        for (var i = 0; i < buttons.length; i++) {
        buttons[i].classList.add('not-clicked');
        buttons[i].classList.remove('clicked'); }
    }
}
.outer {
 border: 2px solid gray;
 margin: 1rem;
 padding: 1rem; 
}
.stickymenuwrapper {
 background-color: #fff;
 transition-duration: 0s;
 padding: 0;
 margin: 0 auto;
 z-index: 995;
 }
.scrabble-menu .hidden {
 display: none;
}
.scrabble-menu .navbar > li {
 display: inline-block;
}
.scrabble-menu ul {
 list-style: none;
 margin-bottom: 0;
 white-space: Nowrap;
 padding: 0;
}
.scrabble-menu ul.navbar {
 background-color: pink;
 padding: 0 1rem;
}
.scrabble-menu li ul {
 position: absolute;
 top: 100%;
 background-color: pink;
 border: 1px solid red;
 padding: 0 12px 0 12px;
}
.scrabble-menu ul.level-2,.scrabble-menu ul.level-3 {
 background-color: yellow;
 top: 0%;
 left: 100%;
 padding-bottom: 0.5rem;
 }
.scrabble-menu ul.level-3 {
 background-color: orange;
 } 
.scrabble-menu li.active > a {
 text-decoration: underline;
}
.scrabble-menu a.separator:hover {
 text-decoration: none;
 }
.scrabble-menu button,.scrabble-menu button:focus {
 background: none;
 border: none;
 height: 2.5rem;
 width: 1.75rem;
 outline:none;
 padding: 0;
}
.scrabble-menu li {
 position: relative;
 display: flex;
 margin: 0;
 padding: 0;
 line-height: 1.5rem;
}
.scrabble-menu .navbar > li > a {
 padding: 0.5rem 0 0.5rem 0.5rem;
 margin-left: 1rem;
}
.scrabble-menu .navbar > li:first-child > a {
 padding: 0.5rem 0.5rem 0.5rem 0;
 margin-left: 0;
}
.scrabble-menu li button:after {
 font-size: 0.8rem;
 position: relative;
 right: -3px;
 top: 0;
}  
.scrabble-menu ul.level-1 > li a {
 padding-top: 0.5rem;
}
.scrabble-menu li button[class^="btn-level"]:after {
 content: "\25B6";
 cursor: pointer;
}
.scrabble-menu .triangle{
}
.scrabble-menu li button[class^="btn-level"].triangle:after {
 content: "\25C0";
}
.scrabble-menu li button.btn-level-1:after {
 content: "\25BC";
}
.scrabble-menu li button.btn-level-1.triangle:after {
 content: "\25B2";
}
<div id="mainbody" class="outer">This is a menu that works with pure html,css and vanilla Javascript. There is no jQuery.<br>There is JS to close the menu when clicking outside the menu and to close each open submenu when its parent's button is clicked. The arrows (including for submenus) switch accordingly.
<div class="row sticky-main-menu">
    <div id="stickymenuwrapper" class="col stickymenuwrapper scrabble-menu">
    <ul id="menucontent" class="navbar">
<li class="item-101 single current active">
<a href="/" class="one">HOME</a></li>
<li class="item-122 single divider deeper parent">
<a class="two">TEST TWO</a>
<button class="btn-level-1" type="button"></button>
<ul id="drop-122" class="hidden level-1">
    <li class="item-121 single">
    <a href="/" class="">Test level 2</a>
    </li>
</ul>
</li>
<li class="item-103 single deeper parent">
<a href="/" class="two">ABOUT</a>
<button class="btn-level-1" type="button"></button>
<ul class="level-1 hidden">
    <li class="item-104 single">
    <a href="/" class="">About us</a>
    </li>
    <li class="item-104 single">
    <a href="/" class="">More</a>
    </li>
</ul>
</li>
</ul>
</div>
</div>
</div>

谢谢。

解决方法

我稍微简化了代码,现在从包装器委托

function openLowerMenu(e) {
  const tgt = e.target;
  e.currentTarget.nextElementSibling.classList.toggle('test1',tgt.type === "button");
  e.currentTarget.nextElementSibling.classList.add('test2',tgt.type !== "button");
}

document.getElementById("stickymenuwrapper").addEventListener("click",function(e) {
  const tgt = e.target;
  if (tgt.type==="button") {
    const level = tgt.className.replace(/[^\d]/g,"");
    [...document.querySelectorAll('ul.level-'+level)].forEach(ul => ul.classList.add("hidden"));
    const show = tgt.classList.contains("triangle")
    tgt.nextElementSibling.classList.toggle("hidden",!show); 
    tgt.classList.toggle("triangle",!show);
  }
});
.row {
  margin: 0 1rem;
}

.outer {
  border: 2px solid gray;
  margin: 1rem;
  padding: 1rem;
}

.sticky-main-menu {
  z-index: 9999;
}

.stickymenuwrapper {
  background-color: #fff;
  transition-duration: 0s;
  padding: 0;
  margin: 0 auto;
  z-index: 995;
}

.scrabble-menu .hidden {
  display: none;
}

.scrabble-menu .navbar>li {
  display: inline-block;
}

.scrabble-menu ul {
  list-style: none;
  margin-bottom: 0;
  white-space: nowrap;
  padding: 0;
}

.scrabble-menu ul.navbar {
  background-color: pink;
  padding: 0 1rem;
  /* text-align: center;*/
}

.scrabble-menu li ul {
  position: absolute;
  top: 100%;
  background-color: pink;
  border: 1px solid red;
  padding: 0 12px 0 12px;
}

.scrabble-menu ul.level-2,.scrabble-menu ul.level-3 {
  background-color: yellow;
  top: 0%;
  left: 100%;
  padding-bottom: 0.5rem;
}

.scrabble-menu ul.level-3 {
  background-color: orange;
}

.scrabble-menu li.active>a {
  text-decoration: underline;
}

.scrabble-menu a.separator:hover {
  text-decoration: none;
}

.scrabble-menu button,.scrabble-menu button:focus {
  background: none;
  border: none;
  height: 2.5rem;
  width: 1.75rem;
  outline: none;
  padding: 0;
}

.scrabble-menu li {
  position: relative;
  display: flex;
  margin: 0;
  padding: 0;
  line-height: 1.5rem;
}

.scrabble-menu .navbar>li>a {
  padding: 0.5rem 0 0.5rem 0.5rem;
  margin-left: 1rem;
}

.scrabble-menu .navbar>li:first-child>a {
  padding: 0.5rem 0.5rem 0.5rem 0;
  margin-left: 0;
}


/* separator line code here */

.scrabble-menu li button:after {
  font-size: 0.8rem;
  position: relative;
  right: -3px;
  top: 0;
}

.scrabble-menu ul.level-1>li a {
  padding-top: 0.5rem;
}

.scrabble-menu li button[class^="btn-level"]:after {
  content: "\25B6";
  cursor: pointer;
}

.scrabble-menu li button[class^="btn-level"].triangle:after {
  content: "\25C0";
}

.scrabble-menu li button.btn-level-1:after {
  content: "\25B2";
}

.scrabble-menu li button.btn-level-1.triangle:after {
  content: "\25BC";
}

.scrabble-menu li button.btn-level-1.triangle2:after {
  content: "\25BC";
}

.scrabble-menu .clicked {}

.scrabble-menu li button[class^="btn-level"].not-clicked:after {
  content: "\25B0";
  cursor: pointer;
}

.scrabble-menu li button.btn-level-1.not-clicked::after {
  content: "\25BC";
}
<div class="row sticky-main-menu">
  <div id="stickymenuwrapper" class="col stickymenuwrapper scrabble-menu">
    <ul id="menucontent" class="scrabblemenu navbar">
      <li class="item-122 single divider deeper parent">
        <a class="two">ITEM ONE</a>
        <button class="btn-level-1 triangle" type="button"></button>
        <ul id="drop-122" class="hidden level-1">
          <li class="item-121 single">
            <a href="/" class="">Item One level 2</a>
          </li>
          <li class="item-134 single deeper parent">
            <a class="nav-header two">Item One level 2 menu heading</a>
            <button class="btn-level-2" type="button"></button>
            <ul id="drop-134" class="level-2 hidden">
              <li class="item-135 single">
                <a href="/" class="">Article under menu heading</a>
              </li>
            </ul>
          </li>
        </ul>
      </li>
      <li class="item-122 single divider deeper parent">
        <a class="two">ITEM TWO</a>
        <button class="btn-level-1 triangle" type="button"></button>
        <ul id="drop-122" class="hidden level-1">
          <li class="item-121 single">
            <a href="/" class="">Item Two level 2</a>
          </li>
          <li class="item-134 single deeper parent">
            <a class="nav-header two">Item Two level 2 menu heading</a>
            <button class="btn-level-2" type="button"></button>
            <ul id="drop-134" class="level-2 hidden">
              <li class="item-135 single">
                <a href="/" class="">Article under menu heading</a>
              </li>
            </ul>
          </li>
        </ul>
      </li>
      <li class="item-103 single deeper parent">
        <a href="/" class="two">ITEM THREE WITH LINK</a>
        <button class="btn-level-1 triangle" type="button"></button>
        <ul class="not-separator level-1 hidden">
          <li class="item-104 single">
            <a href="/" class="">Article under Item Three</a>
          </li>
          <li class="">
            <a class="two separator">Item Three Level 2 separator</a>
            <button class="btn-level-2" type="button"></button>
            <ul id="drop-107" class="level-2 hidden">
              <li class="item-108 single">
                <a href="/" class="">Lower article</a>
              </li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </div>
</div>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。