How do I determine if an element that has a parent `overflow: hidden?` Is hidden?
Let's say I have the following HTML
<div id="someContainer" style="overflow:hidden; height:300px">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
....(countless of similar items)
</div>
How can I determine the first element that is hidden in this case using JQuery or JS? Lots of solutions given on stackOverflow doesn't work for the case with a parent that hasoverflow:hidden
source to share
EDIT: my compulsion made me change this code without jQuery and fix the error
Here's a jsFiddle for a quick test, I repeat the following code:
HTML:
<div id="someContainer" style="overflow:hidden; position:relative; height:26px; background-color: #ffffff;">
<div class="item">A</div>
<div class="item">B</div>
<div class="item">C</div>
</div>
<pre id="output"></pre>
JS (no jQuery):
var i, top, container, output, height;
container = document.getElementById("someContainer");
output = document.getElementById("output");
height = container.offsetHeight;
output.innerText += "Height: " + height + "px\n";
for (i = 0; i < container.children.length; i++)
{
top = container.children[i].offsetTop;
output.innerText += "Top " + i + ": " + top + "px => visible=" + (top < height) + "\n";
}
The output will be:
Height: 26px
Top 0: 0px => visible=true
Top 1: 18px => visible=true
Top 2: 36px => visible=false
The first two items are visible (at least partially, I'll cut B
in half) and the last item is not visible. It extends beyond the bottom edge of the container.
NOTE. I had to add
position: relative;
to the container so that it becomes a link for the children. Otherwise itoffsetTop
will be computed incorrectly under certain circumstances (depending on the external HTML).
source to share
Here is a simple approach that will loop through the children of the container and stop at the first node that meets the conditions
el.offsetTop > parent.offsetHeight + parent.scrollTop;
function find_firstHidden(container, full) {
var items = container.querySelectorAll('*'); // get all nodes
var maxTop = container.scrollTop + container.offsetHeight; // get the container maxTop
var found;
for (var i = 0; i < items.length; i++) {
// if we want to get the first element truncated, add its offsetHeight in the condition
var o_top = full ? items[i].offsetTop + items[i].offsetHeight : items[i].offsetTop;
if (o_top > maxTop) {
found = items[i];
return found;
}
}
return null;
}
// set the element before the first completely hidden node red
find_firstHidden(someContainer)
.previousElementSibling.style.background = 'red';
// set the element before the first partially hidden node green
find_firstHidden(someContainer, true)
.previousElementSibling.style.background = 'green';
.item {
height: 50px;
border: 1px solid;
}
<div id="someContainer" style="overflow:hidden; height:300px">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
Note that if you ever deal with a huge list of nodes, then TreeWalker will probably give better perfs (same conditions will apply)
source to share