简体   繁体   中英

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>

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

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 (ie 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

You could use each() to loop through the .active elements and remove the class if its sibling elements have a ul child:

UPDATED EXAMPLE HERE

$('.navpole .active').each(function(){
    if($(this).siblings().children('ul').length > 0 ){
        $(this).removeClass('active');
    }
});

If you want to keep just the last .active item into each .navpole you can do something like this:

$(document).ready(function () {
    //For each navpole
    $('.navpole').each(function(){
    //Find number of active elements
        var len = $('.active',this).length;
    //Filter that elements and remove class for all elements except the last one
        $('.active',this).filter(function(index){
        return index != len-1;
        }).removeClass('active');
    }) 
});

Check this Demo Fiddle

Try this out. The previous example by adeneo is great, but has issues if you have two active nodes at the same level at the lowest level of the hierarchy and want all of their active states preserved. This version will keep all lowest nodes selected if they're at the same level in the hierarchy.

$(document).ready(function () {
    $('.navpole').each(function () {
        var active = $(this).find(".active").map(function () {
            return $(this).parents().length;
        });
        var maxParents = Math.max.apply(Math, active);
        $(this).find(".active").each(function () {
            if ($(this).parents().length != maxParents) $(this).removeClass("active");
        });
    });
});

here is a fiddle to illustrate: http://jsfiddle.net/CGcr9/1/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM