So I have a side navigation that has a sub-menu in some of the list, and I'm trying to display the sub-menu only when it's clicked.
Here is the HTML
<div >
<ul >
<li onclick="dispDrop()"><a href="">Item 1</a>
<ul >
<li><a href="">Sub-item 1</a></li>
<li><a href="">Sub-item 1</a></li>
<li><a href="">Sub-item 1</a></li>
<li><a href="">Sub-item 1</a></li>
</ul>
</li>
<li><a href="">Item 2</a></li>
<li><a href="">Item 3</a></li>
<li onclick="dispDrop()"><a href="">Item 4</a>
<ul >
<li><a href="">Sub-item 1</a></li>
<li><a href="">Sub-item 1</a></li>
<li><a href="">Sub-item 1</a></li>
<li><a href="">Sub-item 1</a></li>
</ul>
</li>
<li><a href="">Item 5</a></li>
<li><a href="">Item 6</a></li>
</ul>
</div>
Here is its CSS
.nav ul {
display: none;
position: relative;
padding: 0px;
}
.nav li.active ul {
display: block;
}
Here is the javascript
<script type="text/javascript">
const navItem = document.querySelector('.main-menu');
function dispDrop() {
navItem.classList.toggle("active");
}
</script>
At first it was working fine, but when I added a submenu to another list, it started glitching and won't display the submenu.
Is there a way to target only the clicked <li>
and only add/toggle the class to that clicked <li>
?
CodePudding user response:
What you can do is adding this
to onclick="dispDrop()"
And then do the following.
function dispDrop(obj) {
obj.classList.toggle("active");
}
Demo
function dispDrop(obj) {
obj.classList.toggle("active");
}
.nav ul {
display: none;
position: relative;
padding: 0px;
}
.nav li.active ul {
display: block;
}
<div >
<ul >
<li onclick="dispDrop(this)"><a href="#">Item 1</a>
<ul >
<li><a href="">Sub-item 1</a></li>
<li><a href="">Sub-item 1</a></li>
<li><a href="">Sub-item 1</a></li>
<li><a href="">Sub-item 1</a></li>
</ul>
</li>
<li><a href="">Item 2</a></li>
<li><a href="">Item 3</a></li>
<li onclick="dispDrop(this)"><a href="#">Item 4</a>
<ul >
<li><a href="">Sub-item 1</a></li>
<li><a href="">Sub-item 1</a></li>
<li><a href="">Sub-item 1</a></li>
<li><a href="">Sub-item 1</a></li>
</ul>
</li>
<li><a href="">Item 5</a></li>
<li><a href="">Item 6</a></li>
</ul>
</div>
CodePudding user response:
Some issues that I have Identified are listed below.
- You are setting
navItem
asdocument.querySelector('.main-menu')
. This will always returns the first DOM element with that class name. Not your required target. - Your click event will be triggering the click event of the anchor tag, that will result in reload of page.
I have fixed that by toggling the class list of the target elemet from the click tiggered. This will give the required target where the click is triggered.
Call e.preventDefault(); e.stopPropagation();
inside the click event to stop the click event triggering the anchor tag click event.
Working Fiddle
function dispDrop(e) {
e.currentTarget.classList.toggle("active");
e.preventDefault();
e.stopPropagation();
}
.nav ul {
display: none;
position: relative;
padding: 0px;
}
.nav li.active ul {
display: block;
}
<div >
<ul >
<li onclick="dispDrop(event)">
<a href="">Item 1</a>
<ul >
<li><a href="">Sub-item 11</a></li>
<li><a href="">Sub-item 11</a></li>
<li><a href="">Sub-item 11</a></li>
<li><a href="">Sub-item 11</a></li>
</ul>
</li>
<li><a href="">Item 2</a></li>
<li><a href="">Item 3</a></li>
<li onclick="dispDrop(event)">
<a href="">Item 4</a>
<ul >
<li><a href="">Sub-item 12</a></li>
<li><a href="">Sub-item 12</a></li>
<li><a href="">Sub-item 12</a></li>
<li><a href="">Sub-item 12</a></li>
</ul>
</li>
<li><a href="">Item 5</a></li>
<li><a href="">Item 6</a></li>
</ul>
</div>
CodePudding user response:
I rewrite a little bit your code. The problem occurs from the anchor. You can
remove the anchor an style the li tag to have the anchor feeling (cursor: pointer; etc) or
you add a
#
to your href. that will avoid to follow the link
Then I pass with your onclick event the currecnt clickent object. Then you eventHandler knows which element was clicked.
function dispDrop(event) {
event.querySelector('ul').classList.toggle("hide");
}
.nav ul {
position: relative;
padding: 0px;
}
.hide {
display: none;
position: relative;
}
<div >
<ul >
<li onclick="dispDrop(this)">
<a href="#">Item 1</a>
<ul >
<li><a href="">Sub-item 1</a></li>
<li><a href="">Sub-item 1</a></li>
<li><a href="">Sub-item 1</a></li>
<li><a href="">Sub-item 1</a></li>
</ul>
</li>
<li><a href="#">Item 2</a></li>
<li><a href="#">Item 3</a></li>
<li onclick="dispDrop(this)">
<a href="#">Item 4</a>
<ul >
<li><a href="#">Sub-item A </a></li>
<li><a href="#">Sub-item 1</a></li>
<li><a href="#">Sub-item 1</a></li>
<li><a href="#">Sub-item 1</a></li>
</ul>
</li>
<li><a href="#">Item 5</a></li>
<li><a href="#">Item 6</a></li>
</ul>
</div>