I'm building a nested drop down navigation for products and I want to automatically hide any categories that are empty.
Unfortunately server side language does not allow efficient way of doing this, so I thought I could output number of products each category has directly, then use jQuery to remove any empty nodes.
I want to target only the li
's within 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>
Given 1 level of nesting ul
's, I want to remove any li
's that...
have no nested ul
's within them and
have data-num-products == 0
.
So in the example above AAA
is retained because it has ul
children, but CCC
is removed because it has no ul
children and no products.
UPDATE:
It might require 2 passes of removal because if a li contains a ul whose li elements are all removed, then we'll want to remove the ul too.
$( "#top_nav li").filter( function(){
return !this.getElementsByTagName("ul").length && !+this.getAttribute("data-num-products");
}).remove();
This will only remove if there are no UL descendants AND have attribute value of 0
Like this:
$('#top_nav li[data-num-products="0"]:not(:has(ul))').remove();
The selector breakdown is...
'#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
')'
Regarding your updated question, just change :not(:has(ul))
to :not(:has(li))
.
$('#top_nav li[data-num-products="0"]:not(:has(li))').remove();
$("#top_nav li[data-num-products='0']").filter(function() {
return $(this).children("ul").length === 0;
}).remove();
In 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] );
};
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.