简体   繁体   English

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

[英]Disable click from registering on parent li after child ul is clicked

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

The sub menu (treeview-menu) opens when there is a click on li but if the child ul links are click it closes the menu since click gets registered. 当单击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>

my failed attempt as below : 我的失败尝试如下:

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

Worked for me 为我工作

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

There are several issues in your code: 您的代码中存在几个问题:

  • The spelling of stopPropagation is wrong stopPropagation的拼写错误
  • Unclosed brace, mostly because the indentation is off 括号未闭合,主要是因为缩进已关闭
  • The inner event handler references an i that has already passed beyond the length of the treeview list. 内部事件处理程序引用一个i ,该i已经超过了treeview列表的长度。 Be aware that the loop has finished before any clicking happens. 请注意,在完成任何单击之前,循环已完成。 So inside a click handler i is not related to a certain iteration of the loop. 因此,在点击处理程序中, i与循环的某个迭代无关。 You can solve this with giving i block scope (using let ) 您可以通过给i块范围来解决此问题(使用let
  • The inner event handler references an e object that belongs to another event, as you did not define it as parameter 内部事件处理程序引用了一个属于另一个事件的e对象,因为您没有将其定义为参数
  • You assume that every .treeview has exactly one ul child, otherwise the index of related sub menus will not correspond. 您假定每个.treeview都有一个ul子对象,否则相关子菜单的索引将不对应。

Apart from the last point, the following works in your particular example: 除了最后一点,以下内容在您的特定示例中有效:

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

However, because .treeview elements might in theory have 0 or more than 1 child ul , the above solution is not generic enough. 但是,由于.treeview元素理论上可​​能具有0个或多个1个子ul ,因此上述解决方案不够通用。 I would even suggest to only capture clicks on the .treeview > a element, and then you don't even have this propagation issue: 我什至建议只捕获.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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM