Reputation: 23
So essentially I want to keep this as simple as possible, meaning no jquery or bootstrap etc... just straight javascript, HTML and CSS. This is what I have so far
Javscript:
var menuOptions= document.getElementsByClassName("nav");
var hamburger= document.getElementById("nav-btn");
function myFunction() {
hamburger.onclick= menuOptions.style.visibility= 'visible';
}
HTML:
<HTML>
<button onclick="myFunction()">
<span id="nav-btn">
<image src="Menugreen.png" alt="collapsable menu"/>
</span>
</button>
<div class="nav">
<ul>
<li id="Programs"> <a href="Programs.html"> Programs </a> </li>
<li> <a href="Tshirts.html"> T-Shirts </a> </li>
<li id="About"> <a href="About.html"> About </a> </li>
</ul>
</div>
</HTML>
CSS:
.nav {
visibility: hidden;
}
Besides just giving me a solution I would highly appreciate it if you could explain why my current method does not work and why yours does. Thanks in advance!
Upvotes: 1
Views: 3883
Reputation: 16779
There are a few reasons why your current setup does not function:
Document#getElementsByClassName
returns a collection, and you are treating the result like a DOM element. You need to access an index like [0]
to get an actual element.
Your toggle button only works one way, because visibility
is set to visible
but never set back to none
when clicked again.
In myFunction
, hamburger.onclick
should not be assigned to the expression you chose. I am not sure why you tried to assign another click handler, but in order to make that work you would have needed to set it to a function () { ... }
.
Now for my advice:
Use CSS classes to control whether the menu is hidden or not, rather than messing around with the style
property in your JS. You can use the classList
property of DOM elements to .add()
, .remove()
, and .toggle()
a specific class when myFunction
is run. I have chosen to use toggle
because I think that most suits your use case.
Use element.addEventListener
instead of HTML attributes like onclick
.
var menuOptions = document.getElementsByClassName("nav")[0]
var hamburger = document.getElementById("nav-btn")
hamburger.parentNode.addEventListener('click', function myFunction() {
menuOptions.classList.toggle('hidden')
})
.nav.hidden {
visibility: hidden;
}
<button>
<span id="nav-btn">
<img src="Menugreen.png" alt="collapsable menu"/>
</span>
</button>
<div class="nav hidden">
<ul>
<li id="Programs"> <a href="Programs.html"> Programs </a> </li>
<li> <a href="Tshirts.html"> T-Shirts </a> </li>
<li id="About"> <a href="About.html"> About </a> </li>
</ul>
</div>
Upvotes: 0
Reputation: 150020
Two problems:
getElementsByClassName()
returns a list, not a single element (though the list may contain just a single element), and that list doesn't have a .style
property. You can use menuOptions[0]
to access the first (and in this case only) element in the list.
You don't want to say hamburger.onclick=
inside your function, because that would be assigning a new onclick
handler but your function is already being called from the onclick
attribute of your button. (Also, if you were trying to assign a new click handler you'd want hamburger.onclick = function() { /* something */ }
.)
So the minimum change to your existing code to get it to work would be to change this line:
hamburger.onclick= menuOptions.style.visibility= 'visible';
...to this:
menuOptions[0].style.visibility = 'visible';
In context:
var menuOptions= document.getElementsByClassName("nav");
var hamburger= document.getElementById("nav-btn");
function myFunction() {
menuOptions[0].style.visibility = 'visible';
}
.nav {
visibility: hidden;
}
<HTML>
<button onclick="myFunction()">
<span id="nav-btn">
<image src="Menugreen.png" alt="collapsable menu"/>
</span>
</button>
<div class="nav">
<ul>
<li id="Programs"> <a href="Programs.html"> Programs </a> </li>
<li> <a href="Tshirts.html"> T-Shirts </a> </li>
<li id="About"> <a href="About.html"> About </a> </li>
</ul>
</div>
</HTML>
If you want repeated clicks on the button to toggle the menu display on and off then you can test the current visibility:
menuOptions[0].style.visibility =
menuOptions[0].style.visibility === 'visible' ? '' : 'visible';
Expand the following to see that working:
var menuOptions= document.getElementsByClassName("nav");
var hamburger= document.getElementById("nav-btn");
function myFunction() {
menuOptions[0].style.visibility =
menuOptions[0].style.visibility === 'visible' ? '' : 'visible';
}
.nav {
visibility: hidden;
}
<HTML>
<button onclick="myFunction()">
<span id="nav-btn">
<image src="Menugreen.png" alt="collapsable menu"/>
</span>
</button>
<div class="nav">
<ul>
<li id="Programs"> <a href="Programs.html"> Programs </a> </li>
<li> <a href="Tshirts.html"> T-Shirts </a> </li>
<li id="About"> <a href="About.html"> About </a> </li>
</ul>
</div>
</HTML>
Upvotes: 1