Выберите все "li", которые не содержат "ul" в - PullRequest
1 голос
/ 17 января 2012

Я создаю вложенную выпадающую навигацию для продуктов и хочу автоматически скрывать все категории, которые пусты.

К сожалению, язык на стороне сервера не позволяет эффективно делать это, поэтому я подумал, что могу вывести количество продуктов, которые есть у каждой категории напрямую, а затем использовать jQuery для удаления любых пустых узлов.

Я хочу нацелиться только на li в nav#top_nav:

 <nav id="top_nav">
   <nav class="nav1">
     <ul>
       <li data-num-products="0">
         <a href="...">AAA</a>
         <ul>
            <li data-num-products="3"><a href="...">BBB</a></li>
            <li data-num-products="0"><a href="...">CCC</a></li>
         </ul>
       </li>
       <li data-num-products="7"><a href="">DDD</a></li>

     </ul>
   <nav>
 </nav>

Учитывая 1 уровень вложенности ul, я хочу удалить все li, которые ...

  • не имеют вложенных ul в них и

  • имеют data-num-products == 0.

Таким образом, в приведенном выше примере AAA сохраняется, потому что у него есть ul дочерних элементов, но CCC удаляется, потому что у него нет ul дочерних элементов и нет продуктов.

UPDATE:

Для этого может потребоваться 2 прохода удаления, потому что, если li содержит ul, все элементы li которого удалены, мы тоже захотим удалить ul.

Ответы [ 4 ]

3 голосов
/ 17 января 2012
$( "#top_nav li").filter( function(){
    return !this.getElementsByTagName("ul").length && !+this.getAttribute("data-num-products");
}).remove();

http://jsfiddle.net/X2D7y/

Будет удалено, только если нет потомков UL И значение атрибута равно 0

1 голос
/ 17 января 2012

Вот так:

$('#top_nav li[data-num-products="0"]:not(:has(ul))').remove();

Разбивка селектора ...

'#top_nav'                // start at element with "top_nav" id
' '                       // and select descendant...
'li'                      // li elements...
'[data-num-products="0"]' //   ...where attribute "data-num-products" is "0"
':not('                   //   ...but exclude li elements that...
  ':has(ul)'              //        ...have descendant ul elements
')'

Что касается обновленного вопроса, просто измените :not(:has(ul)) на :not(:has(li)).

$('#top_nav li[data-num-products="0"]:not(:has(li))').remove();

http://jsfiddle.net/4YFDd/

0 голосов
/ 17 января 2012

В JavaScript:

var lis = document.querySelectorAll( '#top_nav li[data-num-products="0"]' );
for( var li = 0; li < lis.length; li++ ) { 
    !lis[li].getElementsByTagName( 'ul' ).length && lis[li].parentNode.removeChild( lis[li] );
};

Демо: http://jsfiddle.net/ThinkingStiff/2zS9B/

0 голосов
/ 17 января 2012
$("#top_nav li[data-num-products='0']").filter(function() { 
    return $(this).children("ul").length === 0; 
}).remove();
...