I am working on a school project and we have to do a virtual static menu for a restaurant. What I've done until now is this: when I click on a button, a PopUp shows up and it's contained within the div with the class="menu". The thing is, that I stored all the menu items in a JSON file and thus I don't know how many items I'm going to have inside the menu. If you take a look at the code below, you can see that every menu item is contained within the < li > tag. Now, you can also see that the description start off with the display: none; property. What I am trying to do is this: Using Javascript(I don't think it's possible with plain HTML and CSS), how can I set the style of the description to display: block; of that particular item when either the "title" class or the "svg-container" class is called? In either case, when the svg or the title is pressed, the svg MUST rotate 90 degrees and return to 0 degrees when it's clicked again. The problem is that I don't know how to get the reference of the exact item that has been pressed so I can show it's description...
This is a visual representation of what the menu looks like for now:
And this is why I need the description to be set to display: block;
<div class="menu">
<h2>Our Menu</h2>
<ul>
<li>
<label>
<div class="svg-container"> <img class="arrow" src="right-arrow.svg"/></div>
<span class="title">Fried Fish With Souce</span>
<div class="description" style="display: none;">
This is some internal content.This is some internal content.This is some internal content.
</div>
</label>
</li>
<li>
<label>
<div class="svg-container"> <img class="arrow" src="right-arrow.svg"/></div>
<span class="title">Spaghetti</span>
<div class="description" style="display: none;">
This is some internal content.This is some internal content.This is some internal content.
</div>
</label>
</li>
</ul>
</div>
I tried my best to explain the problem in a clear way, for any questions or uncertainties I am here to answer. Thanks in advance!
EDIT: Thanks everyone for the quick help, but after implementing your code, there is a slight problem, look what happens when the title is too long to fit inside the menu div:
As you can see, the title moves completely on a new line, but what it should just move the content that doesn't fit(WITHOUT splitting the word, only if there is a space) on the new line.
All you need to do is handle the click at the .menu
level and then determine exactly which item within the menu was clicked using [event.target][1]
. This approach leverages event bubbling using a technique called "event delegation".
// Set up event listener on the menu
document.querySelector(".menu").addEventListener("click", function(event){
// The actual item within the menu that was clicked is accessible
// through event.target. So, we'll find the nearest ancestor <li>
// of that, and then search for the .description element within that
// and change the style
event.target.closest("li").querySelector(".description").classList.remove("hidden");
});
.hidden { display:none; }
<div class="menu">
<h2>Our Menu</h2>
<ul>
<li>
<div class="svg-container">
<img class="arrow" src="right-arrow.svg"/>
<span class="title">Fried Fish With Souce</span>
</div>
<div class="description hidden">
This is some internal content.This is some internal content.This is some internal content.
</div>
</li>
<li>
<div class="svg-container">
<img class="arrow" src="right-arrow.svg"/>
<span class="title">Spaghetti</span>
</div>
<div class="description hidden">
This is some internal content.This is some internal content.This is some internal content.
</div>
</li>
</ul>
</div>
Other:
You are not using the label
element correctly. It is meant to
associate a caption with a form field, not regular HTML elements.
If you want the text of the menu item to be next to the arrow, you'll
need that span
to be inside of the previous div
, not outside of
it.
Avoid inline styles when possible and use CSS classes instead.
If you want to be able to toggle the visibility of a clicked item
(show/hide/show/hide, etc.), use .classList.toggle
instead of classList.remove
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With