Skip to content
Advertisement

jQuery collapsible through toggleClass on element

I have an off canvas navigation menu (classname that is enabled via hover-over using jQuery on my WordPress site. It is, as it should be, not visible on page load.

For the mobile version, I want the same nav menu to be activated by clicking on a menu icon (that I’ve given two classes, in this order: mobile-nav-toggle show-nav-mobile). The toggle method seems to only work for a vertical toggle. My solution to replicating the same animation on click rather than hover, is by using the toggleClass method on the icon to toggle between a classname that opens the menu nav (show-nav-mobile) and closes it (hide-nav-mobile) Using the below code:

jQuery(".show-nav-mobile").click(function(){
  jQuery(".offcanvasmainnav").animate({left:'0px' }, 250);
});
jQuery(".mobile-nav-toggle").click(function(){
  jQuery(".mobile-nav-toggle").toggleClass("show-nav-mobile hide-nav-mobile");
});
jQuery(".hide-nav-mobile").click(function(){
  jQuery(".offcanvasmainnav").animate({left:'-640px' }, 250);
});

That doesn’t seem to do the job though. The jQuery opens the offcanvasmain div just fine, but doesn’t close it again.

What is wrong with my approach?

Advertisement

Answer

I assume your element initially looks somewhat like this:

<nav class="mobile-nav-toggle hide-nav-mobile">...</nav>

This means that

a) Both these click handlers will always run when clicking, no matter if the element still has the class hide-nav-mobile:

jQuery(".mobile-nav-toggle").click(function(){
  jQuery(".mobile-nav-toggle").toggleClass("show-nav-mobile hide-nav-mobile");
});
jQuery(".hide-nav-mobile").click(function(){
  jQuery(".offcanvasmainnav").animate({left:'-640px' }, 250);
});

jQuery finds the element at the moment you define the click handler; it doesn’t recheck if the element still has this class when clicking later.

b) This never attaches a click handler:

jQuery(".show-nav-mobile").click(function(){
  jQuery(".offcanvasmainnav").animate({left:'0px' }, 250);
});

because at the time of calling jQuery(".show-nav-mobile") it cannot find any element with that class.

To fix it, do this all in a single click handler:

jQuery(".mobile-nav-toggle").on('click', function(){
  const that = jQuery(this);
  that.toggleClass("show-nav-mobile hide-nav-mobile");
  jQuery(".offcanvasmainnav").animate({left: that.hasClass('show-nav-mobile') ? '0px' : '-640px' }, 250);
});
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement