The ".not()" jQuery selector

by OmShiv

HTML

<ul>
    <li> abc </li>
    <li> abc </li>
    <li>
        <ul>
            <li> def </li>
        </ul>
    </li>
    <li> abc </li>
    <li>
        <ul>
            <li> def </li>
        </ul>
    </li>
</ul>

<!-- Second UL with a reference using a class -->
<ul class="the-parent">
    <li> abc </li>
    <li> abc </li>
    <li>
        <ul>
            <li> def </li>
        </ul>
    </li>
    <li> abc </li>
    <li>
        <ul>
            <li> def </li>
        </ul>
    </li>
</ul>

CSS

ul {
    overflow: hidden;
    border: 1px solid #888;
    width: 40%;
    padding-left: 20px;
}
li {
    list-style-type: none;
    padding: 5px;
}

li > ul {
    margin: 10px 30px;
}

JavaScript

$('li').not(':has(ul)').css('text-decoration','underline');
// Matches all the LIs, and not what you want

$('li').filter(function() {
    return $('ul', this).length == 0;
}).css('font-weight','bold')
// Still Matches all the LIs


// This works, but need a reference to main parent, using a class, id etc.
$('li').not(':has(ul)').filter(function() {
    return $(this).parent().hasClass('the-parent');
}).css('color', 'blue');

// in a simpler way
$('.the-parent > li').not(':has(ul)').css('color', 'blue');