单击子ul后,禁用在父li上注册的单击

问题描述 投票:1回答:2
var treeview = document.querySelectorAll(".treeview");
var submenu = document.querySelectorAll(".treeview ul");
for (var i=0; i<treeview.length; i++;) {
    treeview[i].addEventListener("click", function(e) {
    this.classList.toggle("menu-open");
    e.stoppropagation();
});

单击li时会打开子菜单(treeview-menu),但如果点击了子ul链接,则会关闭菜单,因为click已经注册。

<li class="treeview">
          <a href="#">
            <i class="fa fa-dashboard"></i> <span>Dashboard</span>
          </a>
          <ul class="treeview-menu">
            <li><a href="index.html"><i class="fa fa-circle-o"></i> Dashboard v1</a></li>
            <li class="active"><a href="index2.html"><i class="fa fa-circle-o"></i> Dashboard v2</a></li>
          </ul>
   </li>

我失败的尝试如下:

var treeview = document.querySelectorAll(".treeview");
var submenu = document.querySelectorAll(".treeview ul");
for (var i=0; i<treeview.length; i++) {
    treeview[i].addEventListener("click", function(e) {
    this.classList.toggle("menu-open");
    e.stoppropagation();
    submenu[i].addEventListener("click", function() {
        e.stoppropagation();
    })
});
javascript
2个回答
0
投票

为我工作

    var treeview = document.querySelectorAll(".treeview");
    var submenu = document.querySelectorAll(".treeview ul");
    for (var i=0; i<treeview.length; i++) {
        treeview[i].addEventListener("click", function() {
        this.classList.toggle("menu-open");
    for (var x=0; x<treeview.length; x++){  
        submenu[x].addEventListener("click", function(e) {
            e.stopPropagation();
        })
      }
     });
    }

0
投票

您的代码中存在几个问题:

  • stopPropagation的拼写是错误的
  • 未闭合的支撑,主要是因为压痕脱落
  • 内部事件处理程序引用已经超出i列表长度的treeview。请注意,在发生任何点击之前,循环已完成。因此,在单击处理程序中,i与循环的某个迭代无关。您可以通过给出i块范围来解决这个问题(使用let
  • 内部事件处理程序引用属于另一个事件的e对象,因为您没有将其定义为参数
  • 您假设每个.treeview只有一个ul子项,否则相关子菜单的索引将不对应。

除了最后一点之外,以下内容适用于您的特定示例:

for (let i=0; i<treeview.length; i++) { // block scope
    treeview[i].addEventListener("click", function(e) {
        this.classList.toggle("menu-open");
        e.stopPropagation(); // Spelling!
        submenu[i].addEventListener("click", function(e) { // <-- pass e
            e.stopPropagation(); // Spelling!
        });
    });
} // Fix brace

但是,因为.treeview元素理论上可​​能有0或超过1个孩子ul,所以上述解决方案不够通用。我甚至建议只捕获.treeview > a元素的点击,然后你甚至没有这个传播问题:

for (const link of document.querySelectorAll(".treeview > a")) {
    link.addEventListener("click", function(e) {
        this.parentNode.classList.toggle("menu-open");
    });
}
.menu-open > ul.treeview-menu { display: block }
.treeview > ul { display: none }
<li class="treeview">
    <a href="#">
        <i class="fa fa-dashboard"></i> <span>Dashboard</span>
    </a>
    <ul class="treeview-menu">
        <li><a href="#"><i class="fa fa-circle-o"></i> Dashboard v1</a></li>
        <li class="active"><a href="#"><i class="fa fa-circle-o"></i> Dashboard v2</a></li>
    </ul>
</li>
© www.soinside.com 2019 - 2024. All rights reserved.