Javascript 切换不适用于元素的子元素和子元素的兄弟姐妹

Javascript toggle not working for element's child and child's sibling

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

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

但是,我正在尝试使用 vanilla JavaScript 和 NO jQuery 来执行此操作,并且我知道 JavaScript 需要一个 ID 作为起点。我也明白切换首先添加一个 class 然后删除它。

我创建了一个非常简单的菜单,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>

对于第一个 'get' 行,我也试过这个(基于此处其他帖子的示例):

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

最后我对变量 y 进行了尝试:

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

但都不起作用。

我的 JS 非常基础,我已经尝试解决这个问题将近一个星期了,但我的头发已经所剩无几,所以非常欢迎任何帮助。谢谢。

编辑:删除后续查询。将打开新请求。

  • .getElementById() 要求您传递一个字符串 是一个元素的id,但是你已经通过了 "menucontent>LI>button",这是一个 CSS 选择器,而不是 id 一个元素。
  • .getElementsByTagName() 要求您传递单个字符串 这是标签的名称(即 inputdivp 等)。你是 passing: "LI>button", 不是单个标签的名字.

如果您希望传递 CSS 选择器,请使用 .querySelector() to return the first element that matches your selector or .querySelectorAll() 到 return 所有匹配元素的集合。

只要 HTML 在每个级别中的结构相同,无论您有多少级别,以下代码都有效。

  • 它不需要任何元素具有 ids。
  • 只有一个事件处理程序。
  • 没有循环。
  • 完成工作的函数只是 if 分支中的一行代码。

如果您希望某个关卡开始时处于隐藏状态,只需将 hidden class 添加到 HTML 中的 ul

// 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>