单击孩子ul后,禁止在父li上注册点击

时间:2019-04-13 08:53:38

标签: javascript

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链接,则由于单击被注册,因此它将关闭菜单。

<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();
    })
});

2 个答案:

答案 0 :(得分: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();
        })
      }
     });
    }

答案 1 :(得分: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>