JSFiddle - React, Tailwind, and code Playground
HTML
<p>Green : Element Visible, Red : Element Invisible.</p>
<div id="button">
<button onclick="runTheTest()">Run the test</button>
</div>
<div id="test">
<div id="testarea"></div>
<div id="result"></div>
</div>
CSS
#test {
position: relative;
}
#testarea {
position: relative;
width: 250px;
margin: 0 auto;
overflow: auto;
height: 50px;
}
#testarea > span {
background-color: #F2F2F2;
border:1px solid red;
}
#testarea > span, #result > span {
-moz-box-sizing: border-box;
box-sizing:border-box;
display: inline-block;
width: 50px;
height: 50px;
line-height:50px;
text-align:center;
}
#result {
position: absolute;
overflow: visible;
}
#result > span {
position: absolute;
display: inline-block;
padding: 20px;
border: 2px solid green;
}
JavaScript
var visibleY = function (el) {
var top = el.getBoundingClientRect().top,
rect, el = el.parentNode;
do {
rect = el.getBoundingClientRect();
if (top <= rect.bottom === false) return false;
el = el.parentNode;
} while (el != document.body);
// Check its within the document viewport
return top <= document.documentElement.clientHeight;
};
var ta = document.getElementById('testarea');
// res.offset(ta.offset());
var str = [];
for(var i = 0; i < 100; i++) str.push('<span>', i, '</span>');
ta.innerHTML = str.join('');
function runTheTest(){
var children = ta.children;
var child;
for (var i = 0; i < children.length; i++) {
// var vis = visibleY(children[i]);
// if (!vis) children[i].style.color = 'red';
// if (vis) children[i].style.color = 'green';
child = children[i];
child.style.color = isVisible(child)? 'green' : 'red';
}
}
// Code from RobG
// Return true if an element inside its parents and the viewport
function isVisible(element) {
return isInParents(element) && isInViewport(element);
}
// Return true if an element is inside its parents
function isInParents(el) {
var rect = el.getBoundingClientRect(),
rectP,
visible = true;
while (el && el.parentNode && el.parentNode.getBoundingClientRect && visible) {
el = el.parentNode;
rectP = el.getBoundingClientRect();
visible = rectInRect(rectP, rect);
}
return visible;
}
// Return true if element is inside the viewport
function isInViewport (element) {
var rect = element.getBoundingClientRect();
return rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth);
}
...