user1576978
user1576978

Reputation: 1755

Add class to each level of ul li using jQuery

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.

Upvotes: 0

Views: 4169

Answers (3)

Dan O
Dan O

Reputation: 6090

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);

Upvotes: 3

Pevara
Pevara

Reputation: 14310

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/

Upvotes: 1

Nick R
Nick R

Reputation: 7784

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;}

Upvotes: 0

Related Questions