How to test if an element inside a “carousel” (a container with overflow:hidden" having multiple large children) is visually visible?

人盡茶涼 提交于 2019-12-24 15:24:45

问题


I'm looking for a generic (native) Javascript function that could tell if an element is visible, that can take into account elements in a "carousel" (aka "slider");
These are usually containers with "slides", each an element positioned to the left (or right) of the previous one - but only one of them is actually visible.
An example can be seen in this web page: http://www.technobuffalo.com/2015/07/22/iphone-7-concept-sports-quad-hd-retina-display-wireless-charging/

EDIT: An example for a carousel with 3 slides:

<div class="carousel">
    <div class="slide" style="left:0"><img src="..." /></div>
    <div class="slide" style="left:640px"><img src="..." /></div>
    <div class="slide" style="left:1280px"><img src="..." /></div>
</div>

<style>
   .carousel  {
      width: 640px;
      height: 460px;
      overflow: hidden;
   }
   .slide {
      position: absolute;
      width: 100%;
      height: 100%;
   }

</style>

The function should return false for the images not directly visible in the carousel.

I've tried numerous techniques suggested in answers in SO to questions regarding visibility detection, amongst them - checking offsetParent, offsetLeft, offsetRight, and using getComputedStyle and checking display, and more, but all of them return true for the invisible images in the carousel.


回答1:


Answering my own question.

// This function will return true if an element inside a "carousel" is visually invisible.
function isOffsetHidden(elem) {
  if (elem.nodeName == "BODY") return false;
  // find out if any parent of the element has 'overflow:hidden':
  var p = elem, isOverflow = false;
  while ((p=p.parentNode) && p.nodeName!=="BODY") {
    if (window.getComputedStyle(p)['overflow']=="hidden") {
      isOverflow = true;
      break;
    }
  }
  if (isOverflow) {
    var er = elem.getBoundingClientRect(),
        pr = p.getBoundingClientRect();

    return (er.right < pr.left || er.bottom < pr.top || er.left < pr.right || er.top < pr.bottom);

  }
  return false;
}

It works by first trying to find a container with overflow:hidden, then if the element is inside a container with overflow:hidden and "outside of the bounds" of the container, the function returns true.

In the while loop we need to stop when the element is body, otherwise it will go on until Document and will throw an error saying that the argument for window.getComputedStyle "does not implement the Element interface".

I'll also re-edit the title of the question to be more specific to the problem.



来源:https://stackoverflow.com/questions/31588220/how-to-test-if-an-element-inside-a-carousel-a-container-with-overflowhidden

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!