Question

I tried some jQuery and I want to figure out how to get a sliding menu working. I have a class "dropdown" on a <ul>. A submenu displays for all the <a>'s I click. The submenu <ul>'s have class "sub-menu" appointed to them.

I have gotten quite far in making this work. Now all I want to make sure is that when submenu-items are clicked they behave as they would normally. This is now prevented by preventDefault. Neat function, but I want to disable it for sub-menu <a>'s.

I have the following code:

$(document).ready(function () {
    $('.dropdown > li').click(function () {
        var $el = $('ul', this); // element to toggle
        $('.dropdown > li > ul').not($el).slideUp();
        $(this).find('.sub-menu ').slideToggle();
    });
    $('.dropdown > li').children().children().click(function (e) {
        return false;
    });
    $(".dropdown > li > a").click(function (e) {
        e.preventDefault();
    });
});

I added the preventDefault to avoid the normal routine on the main menu, and I disabled the slideToggle action for the sub-menu.

Now I would like add the default behaviour for the submenu <a>'s. They are doing nothing at the moment.

EDIT: I found the "not" bit of JQuery and I am trying to get that to work (as I haven't had a satisfying answer yet). What I want is to exclude all 's that belong to the class "sub-menu" from the function that slides the sub-menu's. The syntax I came up with is:

$('.dropdown > li').not('ul.sub-menu > li > a').click(function() {
}

But it doesn't work. When I click an that is within it still performs the function. So how would I rephrase the code above for the function above to always perform except when the is within a ?

Was it helpful?

Solution 3

I finally found something that seems to work as I want it to. In the following code (after all "other" subitems have slid up) a check is made whether the current menu-item contains a sub-item that is visible. If not it is slid up, else down.

$(function() {
 $('ul.dropdown > li > a').click(function () {
  var $el = $('ul', this);
  $('.dropdown > li > ul').not($el).slideUp();
  if(  $(this).parent().find('.sub-menu ').is(":visible"))
  {$(this).parent().find('.sub-menu ').slideUp();}
  else
  {$(this).parent().find('.sub-menu ').slideDown();}
 });

 $(".dropdown > li > a").click(function (e) {
    e.preventDefault();
 });

});

Because it explicitly targets the a element of class "dropdown" (i.e. the main-menu-items), the default behaviour of the subitems is untouched. (Because of that, the this.parent() is needed to look for sub-menu-items.)

OTHER TIPS

As i commented,

$('.dropdown > li').children().children().click(function (e) {
    return false;
});

is selecting the submenu links and the return false has the same effect of e.preventDefault().

just take out that bit

You can do for first or any specified element like this:

$(document).ready(function () {
    $('.menu-item').bind('click', function () {
        if($(this).children('ul').length =0){      
            return false;      
        }
       else{
           $(this).children('.sub-menu ').slideToggle();
           return false;
       }    
    });
});

IF HTML code is like this:

<ul class="dropdown">
    <li class="menu-item">
        <a href="#">
      ITEM1
        </a>
    </li>
    <li class="menu-item">
        <a href="#">
      ITEM2
        </a>
        <ul class="sub-menu" >
            <li class="menu-item">
                <a href="#">
                  SUBITEM1
                </a>
            </li>
            <li class="menu-item">
              <a href="#">
                 SUBITEM2
              </a>
            </li>
        </ul>
    </li>
</ul>

For DEMO : http://jsfiddle.net/Pgm7G/16/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top