Why must I click twice to open and close my menu


Hello I got a situation which I do not understand quite well. I have the following setup:

	$(document).ready(function(){
  $('.menuBtn').on('click touch', function () {
		$(this).toggleClass('act');
			if($(this).hasClass('act')) {
				$('.mobileMenu').addClass('act');
				//$('body').addClass('positionfixed');
			}
			else {
				$('.mobileMenu').removeClass('act');
				//$('body').removeClass('positionfixed');
			}
	});
  	});
	.mobile-menu-button{
		display:block;
		position:fixed;
		top:20px;
		left:20px;		
		z-index:99;
    background-color:#19b698;
    padding:5px 10px;
    color:#fff;
    font-family: Open Sans;
    font-weight:bold;
	}
	.mobile-menu-button i{
		font-size:26px;
		background-color:#00adee;
		padding:5px 10px;
		color:#fff;
	}
.mobileMenu {
		background-color: #fff !important;
		position: fixed;
		left: 0;
		top: 0;
		z-index: 100;	  
		height: 100vh;
		width: 100vw;
		display: block;
		text-align: center;
		opacity: 0;
		-webkit-transition: all 500ms cubic-bezier(0.68, -0.55, 0.265, 1.55);
		transition: all 500ms cubic-bezier(0.68, -0.55, 0.265, 1.55);
		-webkit-transform: scale(0);
			  transform: scale(0);
		overflow:hidden;
	}
	.mobileMenu img{
		max-width:90%;
		margin:0 auto;
		margin-top:20px;
		margin-bottom:10px;
		border-bottom:1px dotted #717274;
		padding-bottom:20px;
	}
	.mobileMenu.act {
		opacity: 1;
		-webkit-transform: scale(1);
			  transform: scale(1);
	}
	.mobileMenu.act ul li {
		opacity: 1;
		-webkit-transform: translateX(0);
			  transform: translateX(0);
		display:block !important;
	}
	.mobileMenu ul {
		display: block;
		vertical-align: middle;
	}
	.mobileMenu li {
		padding: 10px 0 !important;
		-webkit-transition: all 400ms 510ms;
		transition: all 400ms 510ms;
		opacity: 0;
	}
	.mobileMenu li:nth-child(odd) {
	  -webkit-transform: translateX(30%);
			  transform: translateX(30%);
	}
	.mobileMenu li:nth-child(even) {
	  -webkit-transform: translateX(-30%);
			  transform: translateX(-30%);
	}
	.mobileMenu li:last-child {
	  -webkit-transform: none;
			  transform: none;
	}
	.mobileMenu a {
	  color: #00adee !important;
	  display: inline-block;
	  font-size: 18px;
	}
	.mobileMenu a.suBtn {
	  color: #fff;
	}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="mobile-menu-button menuBtn">Open</span>
  <nav class="mobileMenu">
  <span class="mobile-menu-button menuBtn">Close</span>						
  <ul>
    <li><a href="index.html">Home</a></li>
    <li><a href="testimonials.html">Testimonials</a></li>
    <li><a href="contact.html">Contact</a></li>
  </ul>
</nav>

Why should I press two times on the open / close button to open / close the menu?

Anyone any idea / fix?

The problem is that you checking for .act on the button instead of the menu. There are two buttons so you need to toggle twice.

Changing:

$(this).toggleClass('act');
if($(this).hasClass('act')) {

to

$('.mobileMenu').toggleClass('act');
if($('.mobileMenu').hasClass('act')) {

fixes it:

	$(document).ready(function(){
  $('.menuBtn').on('click touch', function () {
		$('.mobileMenu').toggleClass('act');
			if($('.mobileMenu').hasClass('act')) {
				$('.mobileMenu').addClass('act');
				//$('body').addClass('positionfixed');
			}
			else {
				$('.mobileMenu').removeClass('act');
				//$('body').removeClass('positionfixed');
			}
	});
  	});
	.mobile-menu-button{
		display:block;
		position:fixed;
		top:20px;
		left:20px;		
		z-index:99;
    background-color:#19b698;
    padding:5px 10px;
    color:#fff;
    font-family: Open Sans;
    font-weight:bold;
	}
	.mobile-menu-button i{
		font-size:26px;
		background-color:#00adee;
		padding:5px 10px;
		color:#fff;
	}
.mobileMenu {
		background-color: #fff !important;
		position: fixed;
		left: 0;
		top: 0;
		z-index: 100;	  
		height: 100vh;
		width: 100vw;
		display: block;
		text-align: center;
		opacity: 0;
		-webkit-transition: all 500ms cubic-bezier(0.68, -0.55, 0.265, 1.55);
		transition: all 500ms cubic-bezier(0.68, -0.55, 0.265, 1.55);
		-webkit-transform: scale(0);
			  transform: scale(0);
		overflow:hidden;
	}
	.mobileMenu img{
		max-width:90%;
		margin:0 auto;
		margin-top:20px;
		margin-bottom:10px;
		border-bottom:1px dotted #717274;
		padding-bottom:20px;
	}
	.mobileMenu.act {
		opacity: 1;
		-webkit-transform: scale(1);
			  transform: scale(1);
	}
	.mobileMenu.act ul li {
		opacity: 1;
		-webkit-transform: translateX(0);
			  transform: translateX(0);
		display:block !important;
	}
	.mobileMenu ul {
		display: block;
		vertical-align: middle;
	}
	.mobileMenu li {
		padding: 10px 0 !important;
		-webkit-transition: all 400ms 510ms;
		transition: all 400ms 510ms;
		opacity: 0;
	}
	.mobileMenu li:nth-child(odd) {
	  -webkit-transform: translateX(30%);
			  transform: translateX(30%);
	}
	.mobileMenu li:nth-child(even) {
	  -webkit-transform: translateX(-30%);
			  transform: translateX(-30%);
	}
	.mobileMenu li:last-child {
	  -webkit-transform: none;
			  transform: none;
	}
	.mobileMenu a {
	  color: #00adee !important;
	  display: inline-block;
	  font-size: 18px;
	}
	.mobileMenu a.suBtn {
	  color: #fff;
	}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="mobile-menu-button menuBtn">Open</span>
  <nav class="mobileMenu">
  <span class="mobile-menu-button menuBtn">Close</span>						
  <ul>
    <li><a href="index.html">Home</a></li>
    <li><a href="testimonials.html">Testimonials</a></li>
    <li><a href="contact.html">Contact</a></li>
  </ul>
</nav>


May I offer a solution where you have a single button controlling the display of the menu instead of two buttons?

Main changes were to increase the z-index of .mobile-menu-button so it's always on top of your menu and to check in the text value of the button and decide whether to open or close it. You could also check if the menu has .act on it instead of checking the text of the button; tomayto, tomahto.

$( document ).ready( function () {
  
  var $mobileMenu = $( '.mobileMenu' );

  $('.menuBtn').on( 'click touch', function () {
  
    var $this = $( this ),
        isOpen = 'Close' === $this.text();
        
    $this.text( isOpen ? 'Open' : 'Close' );
    $mobileMenu.toggleClass( 'act', !isOpen );
    
  } );
  
} );
.mobile-menu-button {
  display: block;
  position: fixed;
  top: 20px;
  left: 20px;
  z-index: 105;
  background-color: #19b698;
  padding: 5px 10px;
  color: #fff;
  font-family: Open Sans;
  font-weight: bold;
  cursor: pointer;
}

.mobile-menu-button i {
  font-size: 26px;
  background-color: #00adee;
  padding: 5px 10px;
  color: #fff;
}

.mobileMenu {
  background-color: #fff !important;
  position: fixed;
  left: 0;
  top: 0;
  z-index: 100;
  height: 100vh;
  width: 100vw;
  display: block;
  text-align: center;
  opacity: 0;
  -webkit-transition: all 500ms cubic-bezier(0.68, -0.55, 0.265, 1.55);
  transition: all 500ms cubic-bezier(0.68, -0.55, 0.265, 1.55);
  -webkit-transform: scale(0);
  transform: scale(0);
  overflow: hidden;
}

.mobileMenu img {
  max-width: 90%;
  margin: 0 auto;
  margin-top: 20px;
  margin-bottom: 10px;
  border-bottom: 1px dotted #717274;
  padding-bottom: 20px;
}

.mobileMenu.act {
  opacity: 1;
  -webkit-transform: scale(1);
  transform: scale(1);
}

.mobileMenu.act ul li {
  opacity: 1;
  -webkit-transform: translateX(0);
  transform: translateX(0);
  display: block !important;
}

.mobileMenu ul {
  display: block;
  list-style: none;
}

.mobileMenu li {
  padding: 10px 0 !important;
  -webkit-transition: all 400ms 510ms;
  transition: all 400ms 510ms;
  opacity: 0;
}

.mobileMenu li:nth-child(odd) {
  -webkit-transform: translateX(30%);
  transform: translateX(30%);
}

.mobileMenu li:nth-child(even) {
  -webkit-transform: translateX(-30%);
  transform: translateX(-30%);
}

.mobileMenu li:last-child {
  -webkit-transform: none;
  transform: none;
}

.mobileMenu a {
  color: #00adee !important;
  display: inline-block;
  font-size: 18px;
}

.mobileMenu a.suBtn {
  color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="mobile-menu-button menuBtn">Open</span>
<nav class="mobileMenu">
  <ul>
    <li><a href="index.html">Home</a></li>
    <li><a href="testimonials.html">Testimonials</a></li>
    <li><a href="contact.html">Contact</a></li>
  </ul>
</nav>

I also added list-style: none; to .mobileMenu ul as I noticed some bullet points. I'm assuming you didn't want those.


Why Two Clicks?

As far as why you had to click twice, you were using toggleClass() on two different buttons to open/close the menu. The first button (Open) would get .act added and the menu would show. Now we're seeing the second button (Close) which doesn't have .act yet, so you click it and toggleClass() adds .act to it (instead of removing .act from the first button (Open) like you might have been expecting). Since a button needs .act on it to hide the menu, you now need to click the second button (Close) a second time to for toggelClass() to remove .act and hide the menu. Now the first button (Open) is shown, which still has .act. But clicking it removes .act, thus necessitating one more click to add .act back to the button and now the menu can be show because the button has .act.

It's more simple to use a single button.


You should use below jQuery code instead of using yours::

$(document).ready(function(){
  $('.menuBtn').on('click touch', function () {
    $(this).toggleClass('act');
    if(!$('.mobileMenu').hasClass('act')) {
      $('.mobileMenu').addClass('act');
      //$('body').addClass('positionfixed');
    }
    else {
      $('.mobileMenu').removeClass('act');
      //$('body').removeClass('positionfixed');
    }
  });
});

Working URL:: https://jsfiddle.net/Lxz9v34L/2/


You have 2 .menuBtn. You could simplify your code to something like this:

$(document).ready(function(){
  $('.menuBtn').on('click touch', function () {
    $('.mobileMenu').toggleClass('act');
    $(this).text($(this).text() === 'Open' ? 'Close' : 'Open')
	});
});
.mobile-menu-button{
		display:block;
		position:fixed;
		top:20px;
		left:20px;		
		z-index:101;
    background-color:#19b698;
    padding:5px 10px;
    color:#fff;
    font-family: Open Sans;
    font-weight:bold;
    cursor: pointer;
	}
	.mobile-menu-button i{
		font-size:26px;
		background-color:#00adee;
		padding:5px 10px;
		color:#fff;
	}
.mobileMenu {
		background-color: #fff !important;
		position: fixed;
		left: 0;
		top: 0;
		z-index: 100;	  
		height: 100vh;
		width: 100vw;
		display: block;
		text-align: center;
		opacity: 0;
		-webkit-transition: all 500ms cubic-bezier(0.68, -0.55, 0.265, 1.55);
		transition: all 500ms cubic-bezier(0.68, -0.55, 0.265, 1.55);
		-webkit-transform: scale(0);
			  transform: scale(0);
		overflow:hidden;
	}
	.mobileMenu img{
		max-width:90%;
		margin:0 auto;
		margin-top:20px;
		margin-bottom:10px;
		border-bottom:1px dotted #717274;
		padding-bottom:20px;
	}
	.mobileMenu.act {
		opacity: 1;
		-webkit-transform: scale(1);
			  transform: scale(1);
	}
	.mobileMenu.act ul li {
		opacity: 1;
		-webkit-transform: translateX(0);
			  transform: translateX(0);
		display:block !important;
	}
	.mobileMenu ul {
		display: block;
		vertical-align: middle;
	}
	.mobileMenu li {
		padding: 10px 0 !important;
		-webkit-transition: all 400ms 510ms;
		transition: all 400ms 510ms;
		opacity: 0;
	}
	.mobileMenu li:nth-child(odd) {
	  -webkit-transform: translateX(30%);
			  transform: translateX(30%);
	}
	.mobileMenu li:nth-child(even) {
	  -webkit-transform: translateX(-30%);
			  transform: translateX(-30%);
	}
	.mobileMenu li:last-child {
	  -webkit-transform: none;
			  transform: none;
	}
	.mobileMenu a {
	  color: #00adee !important;
	  display: inline-block;
	  font-size: 18px;
	}
	.mobileMenu a.suBtn {
	  color: #fff;
	}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="mobile-menu-button menuBtn">Open</span>
  <nav class="mobileMenu">
  <ul>
    <li><a href="index.html">Home</a></li>
    <li><a href="testimonials.html">Testimonials</a></li>
    <li><a href="contact.html">Contact</a></li>
  </ul>
</nav>


$(this).toggleClass('act');

to

$('.menuBtn').toggleClass('act');

because this will return the only span which is clicked not other. Hence it is not going toggle class on both div.

please find working snippet below

$(document).ready(function(){
  $('.menuBtn').on('click touch', function () {
		 $('.menuBtn').toggleClass('act');
			if($(this).hasClass('act')) {
				$('.mobileMenu').addClass('act');
				//$('body').addClass('positionfixed');
			}
			else {
				$('.mobileMenu').removeClass('act');
				//$('body').removeClass('positionfixed');
			}
	});
  	});
.mobile-menu-button{
		display:block;
		position:fixed;
		top:20px;
		left:20px;		
		z-index:99;
    background-color:#19b698;
    padding:5px 10px;
    color:#fff;
    font-family: Open Sans;
    font-weight:bold;
	}
	.mobile-menu-button i{
		font-size:26px;
		background-color:#00adee;
		padding:5px 10px;
		color:#fff;
	}
.mobileMenu {
		background-color: #fff !important;
		position: fixed;
		left: 0;
		top: 0;
		z-index: 100;	  
		height: 100vh;
		width: 100vw;
		display: block;
		text-align: center;
		opacity: 0;
		-webkit-transition: all 500ms cubic-bezier(0.68, -0.55, 0.265, 1.55);
		transition: all 500ms cubic-bezier(0.68, -0.55, 0.265, 1.55);
		-webkit-transform: scale(0);
			  transform: scale(0);
		overflow:hidden;
	}
	.mobileMenu img{
		max-width:90%;
		margin:0 auto;
		margin-top:20px;
		margin-bottom:10px;
		border-bottom:1px dotted #717274;
		padding-bottom:20px;
	}
	.mobileMenu.act {
		opacity: 1;
		-webkit-transform: scale(1);
			  transform: scale(1);
	}
	.mobileMenu.act ul li {
		opacity: 1;
		-webkit-transform: translateX(0);
			  transform: translateX(0);
		display:block !important;
	}
	.mobileMenu ul {
		display: block;
		vertical-align: middle;
	}
	.mobileMenu li {
		padding: 10px 0 !important;
		-webkit-transition: all 400ms 510ms;
		transition: all 400ms 510ms;
		opacity: 0;
	}
	.mobileMenu li:nth-child(odd) {
	  -webkit-transform: translateX(30%);
			  transform: translateX(30%);
	}
	.mobileMenu li:nth-child(even) {
	  -webkit-transform: translateX(-30%);
			  transform: translateX(-30%);
	}
	.mobileMenu li:last-child {
	  -webkit-transform: none;
			  transform: none;
	}
	.mobileMenu a {
	  color: #00adee !important;
	  display: inline-block;
	  font-size: 18px;
	}
	.mobileMenu a.suBtn {
	  color: #fff;
	}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="mobile-menu-button menuBtn">Open</span>
  <nav class="mobileMenu">
  <span class="mobile-menu-button menuBtn">Close</span>						
  <ul>
    <li><a href="index.html">Home</a></li>
    <li><a href="testimonials.html">Testimonials</a></li>
    <li><a href="contact.html">Contact</a></li>
  </ul>
</nav>


In fact, there are two buttons (1 for open, 1 for close).

The 1 first click on "open" works, but then, it doesn't because the close button does not have the act class.

I think you should toggle class on both :

$('.menuBtn').on('click touch', function () {
		**$('.menuBtn')**.toggleClass('act');
    ...
    }