'how to check multiple divs are in viewport when content is absolute positioned offscreen

I am trying to add styling to a slider by checking if the item is within the viewport, this works great until I absolute position the items parent container offscreen using left:-500px; for example.

Here is the code I initially was trying to use.

document.addEventListener("DOMContentLoaded", function() {
var customSlides = document.getElementsByClassName("slide");
function checkForScroll(){
    var customVisibleFraction = 0.75;
    for(var i = 0; i < customSlides.length; i++) {
      var customSlide = customSlides[i];
      var csX = customSlide.offsetLeft, csY = customSlide.offsetTop, csW = customSlide.offsetWidth, csH = customSlide.offsetHeight, csR = csX + csW, //right
          csB = csY + csH, //bottom
          visibleX, visibleY, visible;

      visibleX = Math.max(0, Math.min(csW, window.pageXOffset + window.innerWidth - csX, csR - window.pageXOffset));
      visibleY = Math.max(0, Math.min(csH, window.pageYOffset + window.innerHeight - csY, csB - window.pageYOffset));
      visible = visibleX * visibleY / (csW * csH);
        if (visible > customVisibleFraction) {
            customSlide.style.opacity = '1';
        } else {
            customSlide.style.opacity = '0.5';
        }
    }
}
window.addEventListener('scroll', checkForScroll, false);
window.addEventListener('resize', checkForScroll, false);
});

This works great initially and both left and right side divs have the opacity change as they scroll out of the widow however once I absolute position the container of all these div elements left the script stops working as seen in the following codepen:

https://codepen.io/DigitalDesigner/pen/bGamRRG

If I remove the absolute positioning all works as expected however the slider I am trying to integrate with uses this absolute positioning so looking for a way to make this work.

How can I get this script to function correctly when using -left absolute positioning? I would like to stick with javascript and avoid jQuery as well.



Solution 1:[1]

The correct approach is to use element.getBoundingClientRect():

var rect = element.getBoundingClientRect();
console.log(rect.top, rect.right, rect.bottom, rect.left);

Replace with this:

function checkForScroll(){
  for(var i = 0; i < customSlides.length; i++) {
    const customSlide = customSlides[i];
    const customSlidePos = customSlide.getBoundingClientRect();
    if (customSlidePos.x > 0 && customSlidePos.y > 0 && customSlidePos.x < window.innerWidth && customSlidePos.y < window.innerHeight) {
        customSlide.style.opacity = '1';
    } else {
        customSlide.style.opacity = '0.5';
    }
  }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1