gpr2020
gpr2020

Reputation: 3

jQuery mega menu add/remove class on parent menu item

I'm trying to build a mega menu in Shopify, this is what I have in my HTML:

$('.has-child').on('click', function(event) {
  event.preventDefault();
  $(this).find('.child').toggleClass('menu-visible');
  $('.child').click(function(e) {
    e.stopPropagation();
  });
});
.menu-visible{
color:red}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="parent">
  <li class="parent-main has-child"><a href="/collections">Shop</a>
    <ul class="child">
      <li class=""><a href="/collections">All Collections</a></li>
    </ul>
  </li>
  <li class="parent-main has-child"><a href="/pages/about">About</a>
    <ul class="child">
      <li class=""><a href="/pages/">Child link</a></li>
      <li class=""><a href="/pages/">Child link</a></li>
    </ul>
  </li>
</ul>

It's working as long as I'm clicking to open and close the same parent menu but the issue I'm having is once I click on one parent menu item and then click on another parent menu item it will open the second menu on the first (so if I click on "Shop" and then click "About" it will open the "About" menu on top of the "Shop" menu). I know I need to get it to remove the "menu-visible" class once I click another parent link but I just don't know how... I tried something with .siblings() but it didn't work, maybe I used it wrong...

Any ideas?

-Thanks.

Upvotes: 0

Views: 900

Answers (4)

Alex Gill
Alex Gill

Reputation: 2491

$('.has-child').on('click', function(event) {
  event.preventDefault();

  $(event.currentTarget)
    .find('.child')
    .toggleClass('menu-visible')
    .parent()
    .siblings()
    .find('.child')
    .removeClass('menu-visible')

  $('.child').click(function(e) {
    e.stopPropagation();
  });
});

Upvotes: 1

Luca Di Lenardo
Luca Di Lenardo

Reputation: 36

This one should solve your problem.


$('.has-child').on('click tap', function(event) {
    event.preventDefault();
    if ($(this).find('.child').hasClass('menu-visible')) {
        $(this).find('.child').removeClass('menu-visible'); // toggle current
    } else { 
        $('.menu-visible').removeClass('menu-visible'); // close all
        $(this).find('.child').addClass('menu-visible'); // open current
    }
});

Upvotes: 0

Konstantinos Gounaris
Konstantinos Gounaris

Reputation: 126

Basically what you need is to add the display none to all the other children and toggle the one that you are clicking, by using the not() function you can achieve this without an if statement

<!DOCTYPE html>
<html>
<head>
    <title>List</title>
    <meta charset="utf-8">
    <style type="text/css">
        .d-none{
            display: none;
        }
    </style>
</head>
<body>






<ul class="parent">
  <li class="parent-main has-child"><a href="/collections">Shop</a>
    <ul class="child d-none">
      <li class=""><a href="/collections">All Collections</a></li>
    </ul>
  </li>
  <li class="parent-main has-child"><a href="/pages/about">About</a>
    <ul class="child d-none">
      <li class=""><a href="/pages/">Child link</a></li>
      <li class=""><a href="/pages/">Child link</a></li>
    </ul>
  </li>
</ul>


<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
    $(document).ready(function(){
        $('.parent-main a').click(function(e){
            e.preventDefault();
            $('.child').not($(this).parent().find('.child')).addClass('d-none');
            $(this).parent().find('.child').toggleClass('d-none');

        })
    });
</script>
</body>
</html>

Upvotes: 1

ikiK
ikiK

Reputation: 6532

Simply first remove class from all elements then re-apply on just wanted one.

use if ($(this).find('.child').hasClass("menu-visible")) { in order to toggle and remove from others in same time

$('.has-child').on('click', function(event) {
  event.preventDefault();

  if ($(this).find('.child').hasClass("menu-visible")) {
    $('.child').removeClass("menu-visible")
    $(this).find('.child').removeClass('menu-visible');
  } else {
    $('.child').removeClass("menu-visible")
    $(this).find('.child').addClass('menu-visible');
  }

  $('.child').click(function(e) {
    e.stopPropagation();
  });
});
.menu-visible {
  display: block !important;
}

.child {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="parent">
  <li class="parent-main has-child"><a href="/collections">Shop</a>
    <ul class="child">
      <li class=""><a href="/collections">All Collections</a></li>
    </ul>
  </li>
  <li class="parent-main has-child"><a href="/pages/about">About</a>
    <ul class="child">
      <li class=""><a href="/pages/">Child link</a></li>
      <li class=""><a href="/pages/">Child link</a></li>
    </ul>
  </li>
</ul>

Upvotes: 0

Related Questions