james Burns james Burns - 2 months ago 7
Javascript Question

Need 2 clicks to activate button

I'm trying to earn Javascript, specifically how to add onclick events, and manipulate the DOM.

I set up a real world example on Codepen.

Squish your browser down and you get the classic "hamburger" menu at the top. This works fine except that (after refreshing page) I have to click the hamburger twice to get it to activate.

Here's the code:



var hamburger = document.getElementById("burger"),
menu = document.getElementById("myMenu");


hamburger.addEventListener("click",function(e){
if (menu.style.height==="0px"){
menu.style.height="480px";
hamburger.style.transform="rotate(90deg)";
}else{
menu.style.height="0px";
hamburger.style.transform="rotate(0deg)";
}
});

body {
font: 13pt/130% 'Linden Hill', Times, 'Times New Roman', serif;
background: #BEDFFC;
margin: 0;
}

#burger {
display: none;
color: #BEDFFC;
font-size: 2em;
line-height: 1.25em;
position: relative;
transition: all .25s;
height: 1em;
width: 1em;
left:20px;
top:10px;
transform: rotate(45deg);
}

nav {
width: 100%;
margin: 0 auto;
}

nav ul {
list-style: none;
}

nav a {
font: .9em 'Archivo Narrow', "Helvetica Neue", sans-serif;
display: block;
float: left;
text-align:center;
text-decoration: none;
width: 12%;
margin-right: 1%;
color: rgba(122, 166, 216, 0.87);
border: 1px solid rgba(220, 247, 253, 0.55);
border-radius: 0px 10px 0px 0px;
transition: all .5s ease;
}

nav a.current,
nav a:hover {
color: #dbebf7;
text-decoration: none;
background: #539fd9;
}

@media only screen and (max-width: 800px) {
nav {
background: #265980;
width: 100vw;
height: 60px;
transition: all.5s;
}
nav a {
float: none;
border-radius: 0;
background: hsla(209, 78%, 93%,.75);
width:100%;
height: 40px;
font-size: 30px;
}

#myMenu {
width: 75%;
height: 0px;
margin: 18px auto;
padding: 0;
transition: all .25s;
overflow: hidden;
}
#burger {
display: initial;

}
#burger:hover{
color:white;
}
}


<nav id="myNav">
<div id="burger">&#9776;</div>
<ul id="myMenu">
<li><a href="#" class="current">menu 1</a></li>
<li><a href="#" >menu 2</a></li>
<li><a href="#">menu 3</a></li>
<li><a href="#" title="interactive">menu 4</a></li>
<li><a href="#">menu 5</a></li>
<li><a href="#">menu 6</a></li>
<li><a href="#">menu 7</a></li>
</ul>
</nav>





Now, if I remove the conditional in the addEventListener block, and just change the style of the element, it works fine.



var hamburger = document.getElementById("burger"),
menu = document.getElementById("myMenu");

//works, but doesn't toggle, of course...
hamburger.addEventListener("click",function(e){
menu.style.height="480px";

});

body {
font: 13pt/130% 'Linden Hill', Times, 'Times New Roman', serif;
background: #BEDFFC;
margin: 0;
}

#burger {
display: none;
color: #BEDFFC;
font-size: 2em;
line-height: 1.25em;
position: relative;
transition: all .25s;
height: 1em;
width: 1em;
left:20px;
top:10px;
transform: rotate(45deg);
}

nav {
width: 100%;
margin: 0 auto;
}

nav ul {
list-style: none;
}

nav a {
font: .9em 'Archivo Narrow', "Helvetica Neue", sans-serif;
display: block;
float: left;
text-align:center;
text-decoration: none;
width: 12%;
margin-right: 1%;
color: rgba(122, 166, 216, 0.87);
border: 1px solid rgba(220, 247, 253, 0.55);
border-radius: 0px 10px 0px 0px;
transition: all .5s ease;
}

nav a.current,
nav a:hover {
color: #dbebf7;
text-decoration: none;
background: #539fd9;
}

@media only screen and (max-width: 800px) {
nav {
background: #265980;
width: 100vw;
height: 60px;
transition: all.5s;
}
nav a {
float: none;
border-radius: 0;
background: hsla(209, 78%, 93%,.75);
width:100%;
height: 40px;
font-size: 30px;
}

#myMenu {
width: 75%;
height: 0px;
margin: 18px auto;
padding: 0;
transition: all .25s;
overflow: hidden;
}
#burger {
display: initial;

}
#burger:hover{
color:white;
}
}


<nav id="myNav">
<div id="burger">&#9776;</div>
<ul id="myMenu">
<li><a href="#" class="current">menu 1</a></li>
<li><a href="#" >menu 2</a></li>
<li><a href="#">menu 3</a></li>
<li><a href="#" title="interactive">menu 4</a></li>
<li><a href="#">menu 5</a></li>
<li><a href="#">menu 6</a></li>
<li><a href="#">menu 7</a></li>
</ul>
</nav>





Looking for a pure Javascript, non-jQuery answer here.

What the heck am I doing wrong here? Thanks in advance.

Answer

The problem here is that the menu.style.height property is not initialized as "0px", but "". Modifying your logic to include this case makes the toggle work as expected:

var hamburger = document.getElementById("burger"),
menu = document.getElementById("myMenu");


hamburger.addEventListener("click",function(e){ 
  if (menu.style.height==="0px" || menu.style.height===""){
    menu.style.height="480px";
    hamburger.style.transform="rotate(90deg)";
  }else{
    menu.style.height="0px"; 
    hamburger.style.transform="rotate(0deg)";
  }
});
body {
  font: 13pt/130% 'Linden Hill', Times, 'Times New Roman', serif;
  background: #BEDFFC;
  margin: 0;
}

#burger {
  display: none;
  color: #BEDFFC;
  font-size: 2em;
  line-height: 1.25em;
  position: relative;
  transition: all .25s;
  height: 1em;
  width: 1em;
  left:20px;
  top:10px;
  transform: rotate(45deg);
}

nav {
  width: 100%;
  margin: 0 auto;
}

nav ul {
  list-style: none;
}

nav a {
  font: .9em 'Archivo Narrow', "Helvetica Neue", sans-serif;
  display: block;
  float: left;
  text-align:center;
  text-decoration: none;
  width: 12%;
  margin-right: 1%;
  color: rgba(122, 166, 216, 0.87);
  border: 1px solid rgba(220, 247, 253, 0.55);
  border-radius: 0px 10px 0px 0px;
  transition: all .5s ease;
}

nav a.current,
nav a:hover {
  color: #dbebf7;
  text-decoration: none;
  background: #539fd9;
}

@media only screen and (max-width: 800px) {
  nav {
    background: #265980;
    width: 100vw;
    height: 60px;
    transition: all.5s;
  }
  nav a {
    float: none;
    border-radius: 0;
    background: hsla(209, 78%, 93%,.75);
    width:100%;
    height: 40px;
    font-size: 30px;
  }
  
  #myMenu {
    width: 75%;
    height: 0px;
    margin: 18px auto;
    padding: 0;
    transition: all .25s;
    overflow: hidden; 
  }
  #burger {
    display: initial;

  }
  #burger:hover{
    color:white;
  }
}
<nav id="myNav">
  <div id="burger">&#9776;</div>
      <ul id="myMenu">
      <li><a href="#" class="current">menu 1</a></li>
      <li><a href="#" >menu 2</a></li>
      <li><a href="#">menu 3</a></li>
      <li><a href="#" title="interactive">menu 4</a></li>
      <li><a href="#">menu 5</a></li>
      <li><a href="#">menu 6</a></li>
	 <li><a href="#">menu 7</a></li>
</ul>
</nav>