views:

55

answers:

3

Hi all, I am not an expert at jquery but trying to get a menu to work. Basically, I have a menu made of up to 3 levels of nested lists. The first level has a little arrow has a background image that opens or close when opening the first level list. Any other nested lists don't need to have the background image. My script opens the menu when you click on it and is also supposed to switch the first level list from a class "inactive" to a class "active". Here is the script:

$(document).ready(function(){

$("#left-navigation-holder ul.level1 li.inactive").toggle(function(){

$(this).addClass("active");

}, function () {

$(this).removeClass("active");

});


$("#left-navigation-holder li a").click(function(){

menu = $(this).parent('li').children('ul');

menu.toggle();

});

});

The problem is that the toggle function also happens when clicking on second and third level lists causing the arrows to toggle even if the first level list isn't clicked on. I thought using $("#left-navigation-holder ul.level1 li.inactive").toggle would limit the function to the first level list with a class "inactive".

Any help would be really appreciated.

Ben

+1  A: 

Use the immediate child selector, like this:

$("#left-navigation-holder ul.level1 > li.inactive")
//or...
$("#left-navigation-holder > ul > li > a")

In your selectors, ul.level1 li.inactive means a <li class="inactive"> anywhere beneath the <ul class="level1">, putting the > to make it ul.level1 > li.inactive says to only match that <li> directly beneath that <ul>, not any number of levels beneath.

You could probably do this overall, removing that .level1 unless it serves another purpose:

$("#left-navigation-holder > ul > li.inactive")
Nick Craver
the level1 is useless in that example, it is used later when we move the template in a CMS.ANy of the sample you gave work but do the same thing. The problem is that the click function happens when any list item is clicked and this starts the toggle function. I think I need an if statement after menu.toggle() to change the class only if a first level list was clicked. I just can't figure how to write it.
Ben
I tried something like this:$("#left-navigation-holder li a").click(function(){ menu = $(this).parent('li').children('ul'); menu.toggle();if ($(this).parent('li').style.className == 'inactive') {$(this).parent('li').className = "active";} else {$(this).parent('li').className = "inactive";} });But did not work.
Ben
@Ben - It sounds like it's capturing a `click` bubble from a child element, to prevent this you can prevent the click from child `<li>` elements lower down like this: `$("#left-navigation-holder ul > li > ul").click(function(e) { e.stopPropagation(); });`, you can read more about the effects here: http://api.jquery.com/event.stopPropagation/ Basically we're stopping the bubble from any `<ul>` inside that `<li>` from bubbling up further and causing the events you're binding in the question.
Nick Craver
sorry for the formatting
Ben
You are awesome, stopping the propagation worked! Thanks a lot.Ben
Ben
@Ben - Welcome! If you're all set make sure to accept answers to your question via the check-mark on the left...if you are still having issues please comment and I'll see what I can do :)
Nick Craver
Found the check mark, thanks
Ben
A: 

You can use $("#left-navigation-holder ul > li.inactive") which only selects the direct children of the list (via the > selector).

Felix Kling
A: 

Hi all, Well I am back. i was testing my code this morning and realised that the list that don't have a sub-level don't act right anymore. If I set a link on these, clicking doesn't sends me to the requested URL, but only triggers the change of class between "active" and "inactive". The code looks currently like this:

$(document).ready(function(){

$(".left-navigation-holder li a").click(function(){
    menu = $(this).parent('li').children('ul');
    menu.toggle();
});

$(".left-navigation-holder ul.level1 > li").toggle(function(){
    $(this).addClass("active");
    }, function () {
    $(this).removeClass("active");
});

$(".left-navigation-holder ul > li > ul").click(function(toggle) {
    toggle.stopPropagation();
    return false;
});

});

If I remove the toggle function, the links work.

I am almost sure this is a simple fix but my knowledge is pretty bad I must say. Thanks, Ben

Ben