Question

Hi i am trying to make a simple menu with dropdown. with a simple nested list. Like this:

<ul>
    <li class="niv0">
      <a href="#" class="has_ssmenu closed">Rubrique</a>
      <ul class="ssmenu">
         <li class="niv1">
         <a href="#">Sous-rubrique</a>
         </li>
      </ul>
    </li>
    <li class="niv0">
       <a href="#" class="has_ssmenu closed">Rubrique</a>
       <ul class="ssmenu">
          <li class="niv1">
              <a href="#">ssrub</a>
          </li>
       </ul>
    </li>
    <li class=" niv0">
       <a href="#">rubrique</a>
   </li>
</ul>

I would like, on a click on '.has_ssmenu', the nested list slideToggle or fade and add an '.open' class to it, and of course if there was already a list toggled, close it and remove the '.open' class from it.

My actual jquery code is like that:

       $('.ssmenu').css( 'display','none');

var open = false;
$('.has_ssmenu').toggle(
    function() {
        if (open == false){
            //if its the first time
            $(this).next().slideToggle(400);
            $(this).next().addClass("ssmenu_open");
            $(this).addClass("open");
            $(this).removeClass("closed");
            open=true;
        }
        else{
            //if there is already a list opened
            $('.ssmenu_open').slideToggle(50);
            $('.has_ssmenu').next().removeClass("ssmenu_open");
            $('.has_ssmenu').removeClass("open");
            $('.has_ssmenu').addClass("closed");
            $(this).next().slideToggle(400);
            $(this).next().addClass("ssmenu_open");
            $(this).addClass("open");
            $(this).removeClass("closed");
        }   
    },
    function() {
            $(this).removeClass("open");
            $(this).addClass("closed");
            $(this).next().removeClass("ssmenu_open");
            $(this).next().slideToggle(400);
            open=false;
    });

But it dont work :( I cant deal with the multiple link. How to stop the toggle if i click on an other link ?

Actually with my code, its ok for the first click, if you choose an other link it's still ok: the first opened list is close. But then if you click again on the first link who is now closed, my code bug. He dont get the open class, and he dont close the second opened list.

Maybe there is an easiest way to do it ?

Thanks a lot for your help.

Was it helpful?

Solution

Quite literally I just did this for someone else. Use this and adapt your code around it:

JS Fiddle Demo

HTML:

<ul class="menuHead">
    <li class="title">Menu #1
        <ul class="menu">
            <li>Menu #1 - Link #1</li>
            <li>Menu #1 - Link #2</li>
        </ul>
    </li>
    <li class="title">Menu #2
        <ul class="menu">
            <li>Menu #2 - Link #1</li>
            <li>Menu #2 - Link #2</li>
        </ul>
    </li>
</ul>

jQuery:

$(document).ready(function () {
    $(".menuHead").on('click mouseenter mouseleave', '> li', function (evt) {
        var e = evt || window.event;
        switch (e.type || e.which) {
            case "click":
                if (!($(this).find('.menu').hasClass('stayOpen'))) {
                    $('.stayOpen').fadeOut('fast').removeClass('stayOpen');
                    $(this).find('.menu').addClass('stayOpen');
                } else {
                    $(this).find('.menu').fadeOut('fast').removeClass('stayOpen');
                }
                break;
            case "mouseenter":
                $(this).find('.menu').not('.stayOpen').fadeIn('fast').addClass('open');
                break;
            case "mouseleave":
                $(this).find('.menu').not('.stayOpen').fadeOut('fast').removeClass('open');
                break;
            default:
                break;
        }
    });
});

CSS:

.title {
    width: 150px;
    display: inline-block;
    position: relative;
}
.menu {
    width: 300px;
    top: 100%;
    position: absolute;
    display: none;
}
.open,
.stayOpen {
    display: block;
}

He never accepted as an answer so maybe you'll make better use of it. Here's his post

OTHER TIPS

OK it works fine know. is use this:

$('.ssmenu').css( 'display','none');

$('.has_ssmenu').toggle(function() {
                if (!($(this).next().hasClass('ssmenu_open'))) {
                    $('.has_ssmenu').removeClass('open');
                    $('.ssmenu_open').css( 'display','none').removeClass('ssmenu_open');
                    $(this).addClass('open');
                    $(this).next().fadeIn(400).addClass('ssmenu_open');
                } else {
                    $(this).removeClass('open');
                    $(this).next().fadeOut('fast').removeClass('ssmenu_open');
                }
         },
         function(){
                if (!($(this).next().hasClass('ssmenu_open'))) {
                    $('.has_ssmenu').removeClass('open');
                    $('.ssmenu_open').css( 'display','none').removeClass('ssmenu_open');
                    $(this).addClass('open');
                    $(this).next().fadeIn(400).addClass('ssmenu_open');
                } else {
                    $(this).removeClass('open');
                    $(this).next().fadeOut('fast').removeClass('ssmenu_open');
                }

         });

For this Html:

<ul>
    <li class="niv0">
      <a href="#" class="has_ssmenu">Rubrique</a>
      <ul class="ssmenu">
         <li class="niv1">
         <a href="#">Sous-rubrique</a>
         </li>
      </ul>
    </li>
    <li class="niv0">
       <a href="#" class="has_ssmenu">Rubrique</a>
       <ul class="ssmenu">
          <li class="niv1">
              <a href="#">ssrub</a>
          </li>
       </ul>
    </li>
    <li class=" niv0">
       <a href="#">rubrique</a>
   </li>
</ul>

The .open class is used to add som css3 feature:

#menu{
    background: #FFF;
    width: 100%;
    line-height: 60px;  
    }
#menu li{
    display: inline-block;  
    }
#menu li a{
    color: #CCC;
    position: relative
    }
#menu li > a:not(:only-child):after{
    content: "";
    display: block;
    width: 0;
    height: 0;
    border-color: #FFF transparent transparent;
    border-style: solid;
    border-width: 6px 5px 0 ;
    position: absolute;
    top: 5px;
    right: 10px;
}
#menu li > a.open:before{
    border: solid transparent;
    content: " ";
    height: 0;
    width: 0;
    position: absolute;
    z-index: 999;
    pointer-events: none;
    border-color: transparent;
    border-top-color: #FFF;
    border-width: 10px;
    left: 50%;
    top: 38px;
    margin-left: -10px;
}
.ssmenu{
    background: #4F97A7;
    position: absolute;
    left: 0;
    top: 100%;
    width: 100%;
    z-index: 0; 
}
.ssmenu a {
    color: #fff;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top