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 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:
stopPropagation
is wrong i
that has already passed beyond the length of the treeview
list. 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. You can solve this with giving i
block scope (using let
) e
object that belongs to another event, as you did not define it as parameter .treeview
has exactly one ul
child, otherwise the index of related sub menus will not correspond. 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. I would even suggest to only capture clicks on the .treeview > a
element, and then you don't even have this propagation issue:
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>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.