Stepnage
Stepnage

Reputation: 31

javascript count visible elements

I have been searching the forums but unable find any specific help in relation to my problem. I am trying to design an application using javascript which will count div elements which are either hidden or visible.

I am using

document.getElementById("div-element").childElementCount;

and could use something like:

document.querySelectorAll('#div-element .dic-class').length;

both of which work as intended by returning the total elements.

I am changing the visibility of specific div elements by:

document.getElementById('div-element').style.display == "block or none";

Upvotes: 1

Views: 9158

Answers (5)

Stepnage
Stepnage

Reputation: 31

This is my first time using this forum and wow such good and fast replies.

I ended up using ChillNUT's code and the end result is this:

function IconCount() {
divs = document.querySelectorAll('#IconFX > div');
var divsArray = [].slice.call(divs);
var displayNone = divsArray.filter(function(el) { 
return getComputedStyle(el).display === "none"
});
var displayShow = divsArray.filter(function(el) { 
return getComputedStyle(el).display !== "none"
});
var numberOfHiddenDivs = displayNone.length;
var numberOfVisibleDivs = displayShow.length;
document.getElementById('VisibleIcons').innerHTML = numberOfVisibleDivs;
document.getElementById('HiddenIcons').innerHTML = numberOfHiddenDivs;
}

This way I can call this as a function when anything is hidden or visible and can interact with these output values with another script.

Upvotes: 0

RomanPerekhrest
RomanPerekhrest

Reputation: 92874

While you are changing the visibility of specific div elements by document.getElementById('div-element').style.display = "none"; the count of visible and hidden elements can be easily performed by checking a "generated" style display attribute:

var countHidden = document.querySelectorAll("#div-element .dic-class[style='display: none;']").length;
var countVisible = document.querySelectorAll("#div-element .dic-class:not([style='display: none;'])").length;

Upvotes: 5

chiliNUT
chiliNUT

Reputation: 19573

For something like this Array.prototype.filter comes to mind (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter), but you can't use that on a nodelist, which is what you get when using querySelectorAll, so I would solve this by converting the nodelist to an array, then use filter on that.

To convert a nodelist to an array:

var array = [].slice.call(someNodeList);

(https://davidwalsh.name/nodelist-array)

So, we can do this:

//gives node list
divs = document.querySelectorAll('#div-element > div');
//convert to an array
var divsArray = [].slice.call(divs);
//so now we can use filter
//find all divs with display none
var displayNone = divsArray.filter(function(el) {
    return getComputedStyle(el).display === "none"
});
//and all divs that are not display none
var displayShow = divsArray.filter(function(el) {
    return getComputedStyle(el).display !== "none"
});
//and use length to count
var numberOfHiddenDivs = displayNone.length;
var numberOfVisibleDivs = displayShow.length;

Just a note: its important to use getComputedStyle (https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle) rather than element.style because element.style will not reflect properties applied by css, it will only reflect inline styles.

Second note, this only counts "display:none;" as hidden, if you also want to include visibility:hidden; or some other criteria, use

var displayNone = divsArray.filter(function(el) {
    return getComputedStyle(el).display === "none" ||
        getComputedStyle(el).visibility === "hidden"
});
//and all divs that are not display none
var displayShow = divsArray.filter(function(el) {
    return !(getComputedStyle(el).display === "none" ||
        getComputedStyle(el).visibility === "hidden")
});

Demo:

//gives node list
divs = document.querySelectorAll('#div-element > div');
//convert to an array
var divsArray = [].slice.call(divs);
//so now we can use filter
//find all divs with display none
var displayNone = divsArray.filter(function(el) {
    return getComputedStyle(el).display === "none"
});
//and all divs that are not display none
var displayShow = divsArray.filter(function(el) {
    return getComputedStyle(el).display !== "none"
});
//and use length to count
var numberOfHiddenDivs = displayNone.length;
var numberOfVisibleDivs = displayShow.length;
alert("hidden:"+numberOfHiddenDivs+", visible:"+numberOfVisibleDivs);
#div-element > div{
    width:100px;
    height:50px;
    border:1px solid gold;
    background-color:red;
}
div.hide{
    display:none;
}
<div id='div-element'>
    <div class=hide></div>
    <div class=hide></div>
    <div class=hide></div>
    <div></div>
    <div></div>
    <div></div>
    <div class=hide></div>
    <div></div>
    <div class=hide></div>
    <div></div>
    <div style=display:none;></div>
    <div style=display:none;></div>
</div>

Upvotes: 7

Shomz
Shomz

Reputation: 37701

You can convert the NodeList into an array and then apply reduce to get the number of elements that don't have the display set to none inline:

var divs = Array.prototype.slice.call(document.querySelectorAll('#div-element .dic-class'));

console.log(divs.reduce(function(a, b){return a + (b.style.display != "none" ? 1 : 0)}, 0))
.dic-class {
  display: inline-block;
  margin: 5px;
  height: 50px;
  width: 50px;
  background: green;
  border: 1px solid black;
}
<div id="div-element">
  <div class="dic-class"></div>
  <div class="dic-class"></div>
  <div class="dic-class" style="display: none"></div>
  <div class="dic-class" style="display: none"></div>
  <div class="dic-class"></div>
</div>

If you want to check for applies rules (not just inline ones), you can use getComputedStyle instead.

Upvotes: 1

rrk
rrk

Reputation: 15846

Loop the items and then you can check the style by checking offsetParent , then push to an array.

var elem = document.querySelectorAll('#div-element .dic-class');
var visible = [];
for (i = 0; i < elem.length; i++) {
  _this = elem[i];
  if (_this.offsetParent !== null)
    visible.push(elem[i]);
}
alert(visible.length);
#div-element {
  display: none;
}
<div id="div-element">
  <div class="dic-class"></div>
</div>

Upvotes: 1

Related Questions