Search code examples
jqueryhtmldrop-down-menuslidetogglesubmenu

Toggle all submenus off except the active one


I'm using the following html code to show a navigation menu with submenus and the following jQuery code to toggle on/off submenus:

var container = $('.nav-menu');

container.find('.toggle').click(function(e) {
  var _this = $(this);
  e.preventDefault();
  _this.next('.sub-menu').slideToggle();
  $activeUl = _this.parent('li');
  $parentsUl = $activeUl.parents('ul');
  $('ul.sub-menu', container).not($activeUl).slideUp();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="nav-menu">
  <li class="menu-item"><a class="toggle" href="#">Item 1</a>
    <ul class="sub-menu">
      <li class="menu-item">Item 1.1</li>
      <li class="menu-item">Item 1.2</li>
      <li class="menu-item">Item 1.3</li>
    </ul>
  </li>
  <li class="menu-item"><a class="toggle" href="#">Item 2</a>
    <ul class="sub-menu">
      <li class="menu-item">Item 2.1</li>
      <li class="menu-item">Item 2.2</li>
      <li class="menu-item">Item 2.3</li>
    </ul>
  </li>
  <li class="menu-item"><a class="toggle" href="#">Item 3</a>
    <ul class="sub-menu">
      <li class="menu-item">Item 3.1</li>
      <li class="menu-item">Item 3.2</li>
      <li class="menu-item">Item 3.3</li>
    </ul>
  </li>
</ul>

When clicking a toggle link, I want my code to open its corresponding submenu and close all the other already opened submenus, but I can't make it work.

Any ideas?


Solution

  • At the line $activeUl = _this.parent('li'), you are selecting the parent li element, and then you are trying to negate it from being selected .not($activeUl).

    This doesn't work because the parent element isn't being toggled. You should negate the sibling ul instead:

    Working Example Here

    $container.find('.toggle').click(function (e) {
        var $menu = $(this).next('.sub-menu').slideToggle();
        $('ul.sub-menu', $container).not($menu).slideUp();
    
        e.preventDefault();
    });