Reputation: 31
I am fairly new to coding with javascript; I want to have a three-level collapsible menu, which will expand when clicked. I have written some code but it only works for a two-level menu only. I cannot work out how to alter the script so that the third level will open when clicked too. Any ideas would be most appreciated and do not prefer to use jquery and so if any suggestions with vanilla js would be really helpful for me!
Here is the existing script:
var openListItem=document.getElementsByClassName("nav-links-item");
var i;
for(i = 0; i < openListItem.length; i++){
openListItem[i].addEventListener("click", function() {
var items=this.children;
items[2].classList.add("active");
for (var j = 1; j < i; j++){
var nestedItems = (this.children[2].children[j].children[2]);
nestedItems[i].addEventListener("click", function() {
this.classList.add("active")
});
}
console.log(j,nestedItems);
});
}
I want to click on menu items and it should add an active class to the the items I click and the navigation menu is of three layers.Any help would be highly appreciated.Thank you all :)
Upvotes: 1
Views: 537
Reputation: 20944
Good to hear you are learning JS. Let me try to help you out. You are in the right direction, as far as I can tell from your code.
It seems you are making multiple selections of first the .nav-links-item
elements and then a specific set of children. This seems complicated and easy to lose track over. Let's make it a bit easier.
I noticed in your fiddle that you added the .open-link
class on some of the <li>
elements. I assume that this is because you want those elements to open and show their submenu. That is a good usage of a class, because it gives a clear understanding of what might be going on. Let's use that!
Select all the elements you want to respond on a click, in this case the .open-link
elements, and set the active class to those elements when they are clicked.
var openListItems = document.getElementsByClassName("open-link");
function onListItemClick(event) {
this.classList.add('active');
event.preventDefault();
}
var i = 0;
for(i; i < openListItems.length; i++) {
openListItems[i].addEventListener('click', onListItemClick);
}
Now every time you click a .open-link
element it will get the .active
class. So now you can define in your CSS that whenever a .open-link
has become .open-link.active
it needs to show the next level <ul>
inside it. Something like so:
.open-link > ul {
display: none;
}
.open-link.active > ul {
display: block;
}
Notice the >
in the CSS selector. This is important to make sure that not every ul
in .open-link
is shown, but only the one that is a direct child of .open-link
.
Here is a fiddle with a working example
Hope this helps and good luck!
Upvotes: 1