JSFiddle - React, Tailwind, and code Playground
by AndyE
HTML
<p>This test test the robustness of the isElementVisible function by using it to identify the location of visible elements with a green outline and hidden elements with a red outline.</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: hidden;
height: 50px;
}
#testarea > span {
background-color: gray;
}
#testarea > span, #result > span {
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
function isElementVisible(el) {
var eap,
rect = el.getBoundingClientRect(),
vWidth = window.innerWidth || doc.documentElement.clientWidth,
vHeight = window.innerHeight || doc.documentElement.clientHeight,
efp = function (x, y) { return document.elementFromPoint(x, y) },
contains = "contains" in el ? "contains" : "compareDocumentPosition",
has = contains == "contains" ? 1 : 0x10;
// Return false if it's not in the viewport
if (rect.right < 0 || rect.bottom < 0
|| rect.left > vWidth || rect.top > vHeight)
return false;
// Return true if any of its four corners are visible
return (
(eap = efp(rect.left, rect.top)) == el || el[contains](eap) == has
|| (eap = efp(rect.right, rect.top)) == el || el[contains](eap) == has
|| (eap = efp(rect.right, rect.bottom)) == el || el[contains](eap) == has
|| (eap = efp(rect.left, rect.bottom)) == el || el[contains](eap) == has
);
}
var ta = $('#testarea'),
res = $('#result');
res.offset(ta.offset());
$(new Array(10)).map(function (idx) {
var el = document.createElement('span');
el.textContent = idx;
return el;
}).appendTo('#testarea');
function runTheTest() {
ta.children().map(function (idx, el) {
var resEl = document.createElement('span'),
vis = isElementVisible(el);
$(resEl).offset({top: el.offsetTop, left: el.offsetLeft}).html(' ');
if (!vis)
resEl.style.borderColor = 'red';
return resEl;
}).appendTo(res);
}