Question

I have this nested ul, which are parent -> child -> (grand)child levels.

How can I use jQuery to spot every level adding a class to it so that I can style each level differently?

would be something like:

enter image description here

I couldn't do it with CSS because it needs to work fine at least on IE 7

<ul class="lista-regioes">
    <li class="cat-item cat-item-3 i-have-kids">
     <a href="http://localhost/poraidemochila/site/?local-destino=brasil" title="Ver todos os posts arquivados em Brasil">Brasil</a>
     <ul class="children">
        <li class="cat-item cat-item-13">
        <a href="#" title="#">Norte</a>
        </li>
        <li class="cat-item cat-item-4 i-have-kids">
        <a href="#" title="#">Sul</a>
        <ul class="children">
            <li class="cat-item cat-item-5">
                <a href="http://localhost/poraidemochila/site/?local-destino=parana" title="Ver todos os posts arquivados em Paraná">Paraná</a>
            </li>
        </ul>
    </li>
</ul>
    </li>
</ul>

the classes .cat-item and .cat-item-# are dynamically generated, so I can't use them in css the class .i-have-kids is added by the following js which I found here

 $('li.cat-item:has(ul.children)').addClass('i-have-kids');

but it does not really work since it just looks for elements that have children, and do not separate by levels, as you can see in the markup.

Was it helpful?

Solution 3

Why not just do something like this: http://jsfiddle.net/Rpg88/

HTML

<ul>
    <li><a href="#">link</a></li>
    <li>
        <a href="#">link</a>
        <ul>
            <li><a href="#">link</a></li>
            <li>
                <a href="#">link</a>
                <ul>
                    <li><a href="#">link</a></li>
                    <li><a href="#">link</a></li>
                    <li><a href="#">link</a></li>
                </ul>
            </li>
            <li><a href="#">link</a></li>
        </ul>
    </li>
    <li><a href="#">link</a></li>
</ul>

CSS

ul a { color:red; }
ul ul a {color:orange;}
ul ul ul a {color:lime;}

OTHER TIPS

this.addClasses = function(parent, level) {
    // add a class to all <li> elements on this level:
    parent.children("li").addClass("cat-item-" + level);
    // find any child <ul> elements and run this function on them,
    // making sure to increment the level counter:
    if (parent.children("li").children("ul").length) {
        this.addClasses(parent.children("li").children("ul"), level + 1);
    }
};

// start off by selecting only the top-level <ul> elements:
this.addClasses($("body > ul"), 1);

Actually you do not need to classes to style your menu, you can access the levels in css with the > selector. That is the way I would probably do it.

But that is not the question, so I tried it in javascript. What you want is a recursive function.

Something that would work like this:

function addLevelClass($parent, level) {
    // add a parent class to the ul
    $parent.addClass('parent-'+level);
    // fetch all the li's that are direct children of the ul
    var $children = $parent.children('li');
    // add a child class to the li
    $children.addClass('child-'+level);
    // loop trough each li
    $children.each(function() {
        // get the ul that is a direct child of the li
        var $sublist = $(this).children('ul');
        // if an ul was found
        if ($sublist.length > 0) {
            // add a class to the current li indicating there is a sub list
            $(this).addClass('has-sublist');
            // repeat the process for the sublist, but with the level one higher
            // = recursive function call
            addLevelClass($sublist, level+1);
        }
    });
}

// call the function to add level classes on the upper most ul
addLevelClass($('.list'), 1);

There are probably more efficient ways to do this (js is not my strongpoint), but as an example I think it should work fine. (Feel free to improve!)

I set up a small example here: http://jsfiddle.net/Pevara/UPN33/

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