skip to Main Content

I have two parent items with sub-menus and have the code firing to open the current sub-menu while closing the other open ones.

But I can’t seem to get the .toggleClass() to fire on the open menu to close it (I want to toggle a menu item open/close).

<ul>
    <li class="menu-item-has-children">
        <a href="#">Services</a>
        <ul class="sub-menu">
            <li><a href="#">Thing 1</a></li>
            <li><a href="#">Thing 2</a></li>
        </ul>
    </li>
    <li class="menu-item-has-children">
        <a href="#">Services</a>
        <ul class="sub-menu visible">
            <li><a href="#">Widget 1</a></li>
            <li><a href="#">Widget 2</a></li>
        </ul>
    </li>
</ul>

And here is my current jquery

// main menu toggle of sub-menu
  $(".menu-item-has-children > a").click(function(e) {
    // remove .visible from other .sub-menu
    $(".sub-menu").removeClass('visible');

    // toggle the .visible class on the current parent item
    $(this).next(".sub-menu").toggleClass('visible');

    // prevent the <a> from default behavior
    e.preventDefault();
  });

2

Answers


  1. toggleClass is always do add class if use after removeClass

    // main menu toggle of sub-menu
      $(".menu-item-has-children > a").click(function(e) {
        // check active
        var isCurrentActive = $(this).next('.sub-menu').hasClass('visible')
        
        // remove .visible from other .sub-menu
        $(".sub-menu").removeClass('visible');
    
        // if current menu deactive add visible 
        if(!isCurrentActive){
          $(this).next(".sub-menu").addClass('visible');
        }
    
        // prevent the <a> from default behavior
        e.preventDefault();
      });
    .sub-menu{  display:none }
    .sub-menu.visible{  display:block }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <ul>
        <li class="menu-item-has-children">
            <a href="#">Services</a>
            <ul class="sub-menu">
                <li><a href="#">Thing 1</a></li>
                <li><a href="#">Thing 2</a></li>
            </ul>
        </li>
        <li class="menu-item-has-children">
            <a href="#">Services</a>
            <ul class="sub-menu visible">
                <li><a href="#">Widget 1</a></li>
                <li><a href="#">Widget 2</a></li>
            </ul>
        </li>
    </ul>
    Login or Signup to reply.
  2. This doesn’t work, because $(".sub-menu") selects all sub-menus and removes the visible class from each. Next toggleClass adds again (toggle) the removed visible class.

    If you want to remove visible from the other elements only, you must go up the hierarchy and fetch all sibling elements from the parent. Now visible is removed from the other sub-menu only:

    $(this).parent().siblings().children(".sub-menu").removeClass('visible');
    
    // main menu toggle of sub-menu
    $(".menu-item-has-children > a").click(function(e) {
      // remove .visible from other .sub-menu
      $(this).parent().siblings().children(".sub-menu").removeClass('visible');
    
      // toggle the .visible class on the current parent item
      $(this).next(".sub-menu").toggleClass('visible');
    
      // prevent the <a> from default behavior
      e.preventDefault();
    });
    .sub-menu {
      display: none;
    }
    
    .sub-menu.visible {
      display: block;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <ul>
      <li class="menu-item-has-children">
        <a href="#">Services</a>
        <ul class="sub-menu">
          <li><a href="#">Thing 1</a></li>
          <li><a href="#">Thing 2</a></li>
        </ul>
      </li>
      <li class="menu-item-has-children">
        <a href="#">Services</a>
        <ul class="sub-menu visible">
          <li><a href="#">Widget 1</a></li>
          <li><a href="#">Widget 2</a></li>
        </ul>
      </li>
    </ul>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search