soria
soria

Reputation: 87

ul Tags> li I want to get the number of tags

In the source, we want to find the number of li.q_basket_area belonging to ul#side-recent-area.

The value displayed in the console log is 3 instead of 5.

The console outputs 5 correctly.

$newAt(".recent_number").text('['+ nodesSameClass +']');

In the above case, the value of nodesSameClass is 3.

The style of the diplaynone class is display:none!important;

Is this affected? What's wrong?

Thank you in advance.

var parent = document.getElementById("side-recent-area");
var nodesSameClass = parent.getElementsByClassName("q_basket_area");
console.log(nodesSameClass.length);
.displaynone {display:none!important;}
<span class="recent_number"></span>
<ul id="side-recent-area" class="side-recent-area">
    <li class="q_basket_area xans-record-">
        <div class="q_basket_details displaynone">
            <h3 class="q-heading -size-xs">
                <a href="/show/board.html##param##">product</a>
            </h3>
            <ul class="q_basket_info">
                <li class="q_basket_name">
                    <a href="#;" class="displaynone">(eng : )</a>
                </li>
            </ul>
        </div>
    </li>
    <li class="q_basket_area xans-record-">
        <div class="q_basket_details displaynone">
            <h3 class="q-heading -size-xs">
                <a href="/show/board.html##param##">product</a>
            </h3>
            <ul class="q_basket_info">
                <li class="q_basket_name">
                    <a href="#;" class="displaynone">(eng : )</a>
                </li>
            </ul>
        </div>
    </li>
    <li class="q_basket_area xans-record-">
        <div class="q_basket_details displaynone">
            <h3 class="q-heading -size-xs">
                <a href="/show/board.html##param##">product</a>
            </h3>
            <ul class="q_basket_info">
                <li class="q_basket_name">
                    <a href="#;" class="displaynone">(eng : )</a>
                </li>
            </ul>
        </div>
    </li>
    <li class="q_basket_area displaynone xans-record-">
        <div class="q_basket_details displaynone">
            <h3 class="q-heading -size-xs">
                <a href="/show/board.html##param##">product</a>
            </h3>
            <ul class="q_basket_info">
                <li class="q_basket_name">
                    <a href="#;" class="displaynone">(eng : )</a>
                </li>
            </ul>
        </div>
    </li>
    <li class="q_basket_area displaynone xans-record-">
        <div class="q_basket_details displaynone">
            <h3 class="q-heading -size-xs">
                <a href="/show/board.html##param##">product</a>
            </h3>
            <ul class="q_basket_info">
                <li class="q_basket_name">
                    <a href="#;" class="displaynone">(eng : )</a>
                </li>
            </ul>
        </div>
    </li>
</ul>

Upvotes: 4

Views: 195

Answers (3)

Andrei Voicu
Andrei Voicu

Reputation: 750

You can also use CSS to get the count of list items:

check out: https://www.w3schools.com/css/css_counters.asp

li {
	counter-increment: section
}

ul:after {
	content: "Item Count:" counter(section) "";
	margin-top: 2rem;
	display: block;
}
<ul>
	<li>List item.</li>
	<li>List item.</li>
	<li>List item.</li>
	<li>List item.</li>
	<li>List item.</li>
	<li>List item.</li>
	<li>List item.</li>
	<li>List item.</li>
	<li>List item.</li>
	<li>List item.</li>
	<li>List item.</li>
	<li>List item.</li>
	<li>List item.</li>
	<li>List item.</li>
	<li>List item.</li>
	<li>List item.</li>
	<li>List item.</li>
</ul>

Upvotes: 1

gmastro
gmastro

Reputation: 126

Well the result is not wrong. Check Terry's post how to exclude, anything that you do not wish to get as an element. It answers your question exactly.

An alternative as a solution in a single line is by using querySelectorAll.

var l = document.querySelectorAll( 'ul#side-recent-area li.q_basket_area:not(.displaynone)' ).length;
console.log( l ); // run this to get the result

Upvotes: 2

Terry
Terry

Reputation: 66113

When you select for elements whose class matches q_basket_area, JS will return all the nodes regardless of whether they are visible or not. If you want to filter the node collection such that only visible nodes remain, you will need to:

  1. Convert the node collection into an array
  2. Filter the array, by checking the computed style of the element individually to see if their display property is set to "none"

In JavaScript, this can be done as follow:

  1. Use Array.prototype.slice.call(<NodeCollection>) to convert the collection into an array
  2. Filter the array by checking the computed display property, accessible using window.getComputedStyle(<YourElement>).display, and checking if it matches the string "none" or not.
var parent = document.getElementById("side-recent-area");
var nodesSameClass = parent.getElementsByClassName("q_basket_area")

var visibleNodes = Array.prototype.slice.call(nodesSameClass)
   .filter(function(element) {
     return window.getComputedStyle(element).display !== 'none';
  });

console.log(visibleNodes.length);

See the snippet below as a proof-of-concept demo:

var parent = document.getElementById("side-recent-area");
var nodesSameClass = parent.getElementsByClassName("q_basket_area")
  
var visibleNodes = Array.prototype.slice.call(nodesSameClass)
   .filter(function(element) {
     return window.getComputedStyle(element).display !== 'none';
  });

console.log(visibleNodes.length);
.displaynone {display:none!important;}
<span class="recent_number"></span>
<ul id="side-recent-area" class="side-recent-area">
    <li class="q_basket_area xans-record-">
        <div class="q_basket_details displaynone">
            <h3 class="q-heading -size-xs">
                <a href="/show/board.html##param##">product</a>
            </h3>
            <ul class="q_basket_info">
                <li class="q_basket_name">
                    <a href="#;" class="displaynone">(eng : )</a>
                </li>
            </ul>
        </div>
    </li>
    <li class="q_basket_area xans-record-">
        <div class="q_basket_details displaynone">
            <h3 class="q-heading -size-xs">
                <a href="/show/board.html##param##">product</a>
            </h3>
            <ul class="q_basket_info">
                <li class="q_basket_name">
                    <a href="#;" class="displaynone">(eng : )</a>
                </li>
            </ul>
        </div>
    </li>
    <li class="q_basket_area xans-record-">
        <div class="q_basket_details displaynone">
            <h3 class="q-heading -size-xs">
                <a href="/show/board.html##param##">product</a>
            </h3>
            <ul class="q_basket_info">
                <li class="q_basket_name">
                    <a href="#;" class="displaynone">(eng : )</a>
                </li>
            </ul>
        </div>
    </li>
    <li class="q_basket_area displaynone xans-record-">
        <div class="q_basket_details displaynone">
            <h3 class="q-heading -size-xs">
                <a href="/show/board.html##param##">product</a>
            </h3>
            <ul class="q_basket_info">
                <li class="q_basket_name">
                    <a href="#;" class="displaynone">(eng : )</a>
                </li>
            </ul>
        </div>
    </li>
    <li class="q_basket_area displaynone xans-record-">
        <div class="q_basket_details displaynone">
            <h3 class="q-heading -size-xs">
                <a href="/show/board.html##param##">product</a>
            </h3>
            <ul class="q_basket_info">
                <li class="q_basket_name">
                    <a href="#;" class="displaynone">(eng : )</a>
                </li>
            </ul>
        </div>
    </li>
</ul>


If you are familiar with the ES6 syntax, things get a lot easier:

const parent = document.getElementById("side-recent-area");
const nodesSameClass = parent.getElementsByClassName("q_basket_area")

const visibleNodes = Array.from(nodesSameClass)
   .filter(element => window.getComputedStyle(element).display !== 'none');

console.log(visibleNodes.length);

The difference is that:

  1. You can use const instead of var
  2. You can use Array.from to convert a NodeCollection into an Array
  3. You can use arrow functions in the callback of Array.prototype.filter() method

Upvotes: 1

Related Questions