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

+3


source to share


2 answers


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 it offsetTop

will be computed incorrectly under certain circumstances (depending on the external HTML).

+1


source


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>
      

Run codeHide result


Note that if you ever deal with a huge list of nodes, then TreeWalker will probably give better perfs (same conditions will apply)

0


source







All Articles