jQuery's :visible
selector simply checks the display property to determine visibility status.
(window.getComputedStyle(el).getPropertyValue('display') !== 'none')
While this may suffice for basic needs, it falls short in more complex scenarios. For a thorough solution, continue reading.
Utilizing both Element.getBoundingClientRect() and window.getComputedStyle() can effectively detect element visibility within the viewport.
Solely relying on getBoundingRect() or getComputedStyle() is not optimal for performance. Combining these two functions yields the best results (approximately 22% faster than using getComputedStyle() alone).
function inViewport(els) {
let matches = [],
elCt = els.length;
for (let i=0; i<elCt; ++i) {
let el = els[i],
b = el.getBoundingClientRect(), c;
if (b.width > 0 && b.height > 0 &&
b.left+b.width > 0 && b.right-b.width < window.outerWidth &&
b.top+b.height > 0 && b.bottom-b.width < window.outerHeight &&
(c = window.getComputedStyle(el)) &&
c.getPropertyValue('visibility') === 'visible' &&
c.getPropertyValue('opacity') !== 'none') {
matches.push(el);
}
}
return matches;
}
Here's an example of how to use this function...
var els = document.querySelectorAll('.one'),
visibleEls = inViewport(els);
This method ensures that elements are not hidden (display set to "none"), visible in the viewport, with positive dimensions, and fully contained within the viewport boundaries.