'How can I toggleClass on this element and hide others?

I would like to toggle show a megamenu clicking on his parent tag and at the same time close all other megamenu if opened.

with my basic example code (just to explain the problem) I can open the current megamenu, close the others but clicking another time on the current it remains opened...

any solutions? jquery or vanilla is not a problem. Thanks!

this is my markup (with tailwindcss):

let hasMegamenu = $('.has-megamenu');

hasMegamenu.on('click', function() {
  $('.megamenu').addClass('hidden');
  var thisMM = $(this).find('.megamenu');
  if (thisMM.hasClass('hidden')) {
    console.log('has hidden');
    thisMM.removeClass('hidden');
  } else {
    console.log('has not hidden');
    thisMM.addClass('hidden');
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<nav>
  <ul>
    <li class="has-megamenu">Link1
      <div class="megamenu hidden">
        <ul>
          <li><a href="#">Sublink1</a></li>
          <li><a href="#">Sublink2</a></li>
        </ul>
      </div>
    </li>
    <li class="has-megamenu">Link2
      <div class="megamenu hidden">
        <ul>
          <li><a href="#">Sublink1</a></li>
          <li><a href="#">Sublink2</a></li>
        </ul>
      </div>
    </li>
  </ul>
</nav>


Solution 1:[1]

I would suggest a different approach:

  • make Megamenus CSS hidden by default .has-megamenu .megamenu{display:none;}
  • use a .is-open instead - directly on the .has-megamenu element
  • Use .not() to filter out the clicked one and remove the class .is-open
  • Use .toggleClass() to toggle the clicked one's class .is-open
  • There's still yet something to fix:
    If you want to be able to click on your Megamenu child but not abruptly close the parent you need to detect who initiated the click, the button or the megamenu:

const $hasMegamenu = $(".has-megamenu");

$hasMegamenu.on("click", function(evt) {
  if ($(evt.target).closest(".megamenu").length) return; // Allow clicks inside the megamenu

  $hasMegamenu.not(this).removeClass("is-open"); // Close all (but this)
  $(this).toggleClass("is-open"); // Toggle this
});

// Close if clicked outside
$(document).on("click", (evt) => {
  if (!$(evt.target).closest("nav").length) {
    $hasMegamenu.removeClass("is-open");
  }
});
.has-megamenu .megamenu { display: none; }
.has-megamenu.is-open .megamenu { display: block; }
<nav>
  <ul>
    <li class="has-megamenu">Link1
      <div class="megamenu">
        <ul>
          <li><a href="#">Sublink1</a></li>
          <li><a href="#">Sublink2</a></li>
        </ul>
      </div>
    </li>
    <li class="has-megamenu">Link2
      <div class="megamenu">
        <ul>
          <li><a href="#">Sublink1</a></li>
          <li><a href="#">Sublink2</a></li>
        </ul>
      </div>
    </li>
  </ul>
</nav>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1