首页>Program>source

在菜单中,我尝试使用JavaScript在不同的项目级别上控制类切换.由于菜单是动态生成的,因此我无法在菜单项或元素中添加单个ID(部分原因是菜单可能在页面上出现两次,然后会有重复的ID)。

我要做的是根据项目的级别自动创建数据切换值.希望这将阻止元素中的标准下拉切换切换其父级而不是其子级。

但是,我正在尝试使用原始JavaScript和无jQuery来实现此功能,并且我了解JavaScript需要以ID作为起点.我也了解,切换首先添加一个类,然后将其删除。

我创建了一个非常简单的菜单CSS和JS来演示我正在尝试做的事情:

function myFunction() {
   var x = document.getElementById("test").getElementsByTagName("LI>button");
for (var i = 0; i < x.length; i++) {
   x[i].addEventListener("click", toggle);
   function toggle() {
   var y = document.getElementById("test").getElementsByTagName("LI>button").nextSibling;
    y[0].classList.toggle("dropdown1");
    }
  }
}
<style>
.mystyle {
  width: 100%;
  padding: 25px;
  background-color: coral;
  color: white;
  font-size: 25px;
  box-sizing: border-box;
}
.dropdown0 {
 display: none;
 }
.dropdown1 {
 display: block;
 }
</style>
<div id="test">
  <ul>
    <li class="nav-item single">Single Level 1
    <a class="nav-link one" href="/">HOME</a>
    </li>
    <li class="nav-item single parent">Parent
    <a class="nav-link one">PARENT</a><button onclick="myFunction()">Try it</button>
    <ul class="nav-child dropdown0 dropdown-menu">
        <li class="nav-item single">Single Level 2
        <a class="nav-link one" href="/">LEVEL 2</a>
        </li>
    </ul>
    </li>
  </ul>
</div>

对于第一行"获取"行,我也尝试过此操作(基于此处其他文章的示例):

var x = document.getElementById("menucontent>LI>button");

最后,我为var y进行了尝试:

var y = document.getElementById("menucontent").getElementsByTagName("LI>UL");

但都不行。

我的JS非常基础,我已经将其整理了将近一个星期,而且我的头发还很少,因此非常欢迎您提供帮助.谢谢。

更新: Marcus的解决方案按预期工作(尽管在使用Joomla时,我不得不将脚本放在模板的index.php文件的底部,因为当我将其放在template.js文件中时,代码被忽略了。)

但是,现在我单击顶部的同级对象时无法关闭打开的子菜单.这是到目前为止显示代码的新片段:

// Marcus's script
document.getElementById("menucontent").addEventListener("click", closeSubMenu);
function closeSubMenu(event) {
  // All clicks anywhere within the "test"element will be handled here
  // You can find out which specific element triggered the event with event.target. Then, you can access other elements relative to the
  // event.target. 
  
  // First, make sure it was a button that was clicked
  if(event.target.type === "button"){
    // Here, we look for the next sibling element
    // and toggle its use of the "hidden" class.
    event.target.nextElementSibling.classList.toggle("hidden");
  }
}
// My attempt to toggle class when top level clicked (e.g. from 'About' dropdown to 'Test Two' dropdown, but this first line causes an error so it is commented out:
//document.getElementById("menucontent").querySelectorAll("level-1").addEventListener("click", closeSiblingMenus);
function closeSiblingMenus(event) {
  if (event.target.className.contains("level-1")){
    event.target.nextElementSibling.classList.toggle("hidden");
  }
}
.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 .collapsing {
 transition: unset !important;
 }
.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 a:hover,
.scrabble-menu li.active > a {
 text-decoration: underline;
}
.scrabble-menu button,
.scrabble-menu button:focus {
 background: none;
 border: none;
 height: 2.5rem;
 width: 1.75rem;
 outline:none;
 padding: 0;
}
.scrabble-menu .button-div {
 width: 1rem; /*2rem;*/
}
.scrabble-menu .nav-item .parent {
 position: relative;
}
.scrabble-menu li {
 position: relative;
 display: flex;
 margin: 0;
 padding: 0;
}
.scrabble-menu li > a {
 padding: 0.5rem 0.5rem 0.5rem 1.5rem;
}
.scrabble-menu li:first-child > a {
 padding: 0.5rem 0.5rem 0.5rem 0;
}
.scrabble-menu li:last-child > a {
 padding: 0.5rem 0 0.5rem 1.5rem;
}
.scrabble-menu li {
 line-height: 1.5rem;
 padding-top: 0;
 text-align: center;
}
.scrabble-menu li.separator-line {
 position: relative;
 height: 1rem;
 display: inline-block;
 width: 100%;
}
.scrabble-menu li.separator-line a,
.scrabble-menu .separator-line span {
 display: none;
}
.scrabble-menu li.separator-line:after {
 position: absolute;
 height: 1px;
 top: 60%;
 width: 100%;
 border-top: 1px solid darkgray;
 border-bottom: 1px solid lightgray;
 margin: 0 0;
 content: "";
}  
.scrabble-menu li.divider > a:after,
.scrabble-menu li button:after {
 font-size: 0.8rem;
 position: relative;
 right: -3px;
 top: 0;
}  
.scrabble-menu .dropdown-menu {
 min-width: 7rem;
}
.scrabble-menu li.parent button[aria-expanded="false"] ~ ul.hide {
 display: none;
}
.scrabble-menu li.parent button[aria-expanded="true"] ~ ul.hide {
 display: block;
}
.scrabble-menu li. button:after {
 right: 0;
}
.scrabble-menu li button:after {
 content: "\25BC";
}
.scrabble-menu li a[aria-expanded="true"]:after,
.scrabble-menu li button[aria-expanded="true"]:after {
 content: "\25B2";
}
.scrabble-menu li a[aria-expanded="false"]:after,
.scrabble-menu li button[aria-expanded="false"]:after {
 content: "\25BC";
}  
.scrabble-menu ul.level-1,
.scrabble-menu ul.level-2 {
 position: absolute;
 top: 100%;
 background-color: pink;
 border: 1px solid red;
 padding: 0 12px 0 12px;
}
.scrabble-menu ul.level-2 {
 position: absolute;
 top: 0%;
 left: 100%;
 }
.scrabble-menu ul.ul-two  {
 background-color: yellow;
}
.scrabble-menu .nav-link.two {
 padding: 0.5rem 0.5rem 0.5rem 0;
}
.scrabble-menu {
 margin: 0;
 padding: 0.5rem 0;
}
.scrabble-menu .hidden {
 display: none;
}
<div id="main-outer" class="outer">This is a menu that works with pure html, css and vanilla Javascript. There is no jQuery.</div>
<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 type="button"></button>
<ul id="drop-122" class="hidden level-1">
    <li class="item-121 single">
    <a href="/" class="">Test level 2</a>
    </li>
    <li class="item-134 single deeper parent">
    <a class="nav-header two">Test Two menu heading</a>
    <button 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">ABOUT</a>
<button type="button"></button>
<ul class="not-separator level-1 hidden">
    <li class="item-104 single">
    <a href="/" class="">About us</a>
    </li>
    <li class="">
    <a class="two">Level 2 separator</a>
    <button 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>
    <li class="item-104 single">
    <a href="/" class="">More</a>
    </li>
    <li class="">
    <a class="two">Another Level 2 separator</a>
    <button type="button"></button>
    <ul id="drop-107" class="level-2 hidden">
        <li class="item-108 single">
        <a href="/" class="">Another Lower article</a>
        </li>
        <li class="">
        <a class="two">Level 3 separator</a>
        <button type="button"></button>
        <ul id="drop-107" class="level-2 hidden">
            <li class="item-108 single">
            <a href="/" class="">Level 3 article</a>
            </li>
        </ul>
        </li>
    </ul>
    </li>
</ul>
</li>
</ul>
</div>
</div>

谢谢。

最新回答
  • 1月前
    1 #

      .getElementById() 要求您传递一个字符串 是 id 元素,但是您已经通过了 "menucontent>LI>button" ,这是CSS选择器,而不是 id 元素。

      .getElementsByTagName() 要求您传递一个字符串 这是标签的名称(即 inputdivp 等).你是 传递: "LI>button" ,这不是单个标签的名称。

      如果您希望传递CSS选择器,请使用 .querySelector() 返回与选择器或 .querySelectorAll()匹配的第一个元素 返回所有匹配元素的集合。

      下面的代码无论您有多少级都可以工作,只要每个级中的HTML具有相同的结构即可。

        It doesn't require any of the elements to have id

        只有一个事件处理程序。

        没有循环。

        完成工作的函数只是 if内部的一行代码 分支。

        如果您希望一个关卡开始隐藏,只需添加 hiddenul的类 在HTML中。

        // Don't set up events in the HTML with onXyz attributes.
        // Separate your JavaScript from your HTML. Also, just 
        // set up one event handler on the ancestor of the whole
        // list and handle any clicks within it there.
        document.getElementById("test").addEventListener("click", myFunction);
        function myFunction(event) {
          // All clicks anywhere within the "test" element will be handled here
          // You can find out which specific element triggered the event with
          // event.target. Then, you can access other elements relative to the
          // event.target. 
          
          // First, make sure it was a button that was clicked
          if(event.target.type === "button"){
            // Here, we look for the next sibling element
            // and toggle its use of the "hidden" class.
            event.target.nextElementSibling.classList.toggle("hidden");
          }
        }
        
        li {
          width: 100%;
          padding: 25px;
          background-color: coral;
          color: white;
          font-size: 25px;
          box-sizing: border-box;
        }
        /* This one class will take care of both being 
           visible and not being visible. When the class
           is applied, the element will not be visible.
           When the class is removed, it will go back 
           to being visible. There is no need to make a
           second class. */
        .hidden {
           display: none;
        }
        
        <div id="test">
          <ul>
            <li class="nav-item single">Single Level 1
              <a class="nav-link one" href="/">HOME</a>
            </li>
            <li class="nav-item single parent">Parent
              <a class="nav-link one">PARENT</a>
              <button type="button">Try it</button>
              <ul class="nav-child dropdown-menu">
                  <li class="nav-item single">Single Level 2
                    <a class="nav-link one" href="/">LEVEL 2</a>
                  <button type="button">Try it</button>
                    <ul class="nav-child dropdown-menu">
                        <li class="nav-item single">Single Level 3
                          <a class="nav-link one" href="/">LEVEL 3</a>
                        <button type="button">Try it</button>
                        </li>
                    </ul>
                  </li>
              </ul>
            </li>
          </ul>
        </div>
        

  • r:如何在一个几何图形而不是另一个几何图形上绘制网格
  • Word 2016:word 2016-如何在"重复节属性"菜单-VBA中隐藏"允许用户添加和删除节"功能?