Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery remove class from UL hierarchy except for

See fiddle: http://jsfiddle.net/3mpire/yTzGA/1/

Using jQuery how can I remove the "active" class from all LIs except for the one furthest (deepest) from the root?

<div class="navpole">
    <ul>
        <li class="active"><a href="#">Lorem ipsum</a></li>
        <li><a href="#">Lorem ipsum</a>
            <ul>
                <li class="active"><a href="#">Lorem ipsum</a></li>
                <li><a href="#">Lorem ipsum</a></li>
                <li><a href="#">Lorem ipsum</a>
                     <ul>
                          <li class="active"><a href="#">Lorem ipsum</a></li>
                          <li><a href="#">Lorem ipsum</a></li>
                     </ul>
                </li>
                <li><a href="#">Lorem ipsum</a></li>
            </ul>
        </li>
        <li><a href="#">Lorem ipsum</a></li>
        <li><a href="#">Lorem ipsum</a></li>
    </ul>
</div>

This is the desired result:

<div class="navpole">
    <ul>
        <li><a href="#">Lorem ipsum</a></li>
        <li><a href="#">Lorem ipsum</a>
            <ul>
                <li><a href="#">Lorem ipsum</a></li>
                <li><a href="#">Lorem ipsum</a></li>
                <li><a href="#">Lorem ipsum</a>
                     <ul>
                          <li class="active"><a href="#">Lorem ipsum</a></li>
                          <li><a href="#">Lorem ipsum</a></li>
                     </ul>
                </li>
                <li><a href="#">Lorem ipsum</a></li>
            </ul>
        </li>
        <li><a href="#">Lorem ipsum</a></li>
        <li><a href="#">Lorem ipsum</a></li>
    </ul>
</div>
like image 356
Charles Wesley Avatar asked Jan 29 '14 20:01

Charles Wesley


2 Answers

Sort them by number of parents and exclude the last one as that will be the one nested the furthest regardless of markup, and remove the class on the rest of them

$('.active').sort(function(a,b) {
    return $(a).parents().length > $(b).parents().length;
}).not(':last').removeClass('active');

FIDDLE

To do it for each navpole, just wrap it in a each()

$('.navpole').each(function() {
    $('.active', this).sort(function(a,b) {
        return $(a).parents().length > $(b).parents().length;
    }).not(':last').removeClass('active');
});

FIDDLE

like image 104
adeneo Avatar answered Nov 09 '22 04:11

adeneo


Note: This assumes that there is only a single path from the root to the deepest .active element, which contains all .active Elements under that root (i.e. no branching). If that cannot be guaranteed, then this solution won't work.

$('.navpole .active').slice(0, -1).removeClass('active');

Since the order of the selected elements is the order in which their appear in the document, the "deepest" element is inevitably the last one, so we have to remove the class from every selected element, but the last one.

DEMO

like image 39
Felix Kling Avatar answered Nov 09 '22 05:11

Felix Kling