drake035
drake035

Reputation: 2877

How to make a click anywhere on the screen close mobile menu that is controlled by jQuery toggle() function?

My mobile menu is opened/closed by a jQuery toggle() function. Besides the ability to close it by clicking again the same hamburger icon used to open it, I also want the ability to close it by clicking anywhere on the screen while it's open. However such click anywhere on the screen "disturbs" the toggle() function in the following way: once the menu open, if I close it by clicking anywhere on the screen then click the mobile menu icon again to open it, it works only the second time I click it (because the toggle() function didn't "know" that I closed the menu by clicking on the screen).

How to fix this problem?

JS:

$( '.header__menu_icon' ).toggle( function() {
  $( '.wrap' ).removeClass( 'mobile_menu_opening mobile_menu_closing' );
  $( '.wrap' ).addClass( 'mobile_menu_opening' ); 
}, function() {
  $( '.wrap' ).removeClass( 'mobile_menu_opening mobile_menu_closing' );
  $( '.wrap' ).addClass( 'mobile_menu_closing' ); 
});
$( document ).click(function() {
  $( '.wrap' ).removeClass( 'mobile_menu_opening mobile_menu_closing' );
  $( '.wrap' ).addClass( 'mobile_menu_closing' ); 
});
$( '.mobile_menu' ).click(function(event) {
  event.stopPropagation();
});

HTML:

<body>
<div class='wrap'>
  <div class='header'>
    <div class='mobile_menu'>
      ...
    </div>
  </div>
</div>
</body>

CSS:

@keyframes mobile_menu_opening {
  0% { transform: translateX(0px); }
  100% { transform: translateX(-280px); }
}
@keyframes mobile_menu_closing {
  0% { transform: translateX(-280px); }
  100% { transform: translateX(0px); }
}
.mobile_menu_opening {
  animation-name: mobile_menu_opening;
  animation-duration: 2s;
}
.mobile_menu_closing {
  animation-name: mobile_menu_closing;
  animation-duration: 1s;
}
.wrap {
  position: relative;
}

Upvotes: 1

Views: 486

Answers (2)

Lowkase
Lowkase

Reputation: 5699

Use the NOT specifier

$( "body:not(.mobile_menu)" ).click(function() {
    $("").removeClass("");
    - or -
   $("").toggle("");
});

Upvotes: 0

Mila
Mila

Reputation: 608

I would achieve that by simply avoiding the toggle function. Besides, your code can be optimized the following way:

function menuToggle() {
  var openClass = 'mobile_menu_opening';
  var closedClass = 'mobile_menu_closing';
  var $wrap = $('.wrap');
  if ($wrap.hasClass(openClass)) {
    $wrap.removeClass(openClass);
    $wrap.addClass(closedClass);
  } else {
    $wrap.removeClass(closedClass);
    $wrap.addClass(openClass);
  }
}

$('.header__menu_icon').on('click', function() {
  menuToggle();
});

$(document).on('click', function() {
  menuToggle();
});

$('.mobile_menu').on('click', function(event) {
  event.stopPropagation();
});

Upvotes: 1

Related Questions