简体   繁体   English

检查元素的一部分是否在视口中

[英]Check if a piece of the element is in viewport

I am working on a Javascript code for checking if element is in viewport.我正在编写用于检查元素是否在视口中的 Javascript 代码。 But now I have a code that returns only true if the element is 100% in the viewport.但是现在我有一个代码,只有当元素在视口中为 100% 时才返回 true。 Is there a way for example if there are 10 pixels returns true or if a percentage... of the element is in the viewport return true?有没有办法,例如,如果有 10 个像素返回 true 或者如果元素的百分比......在视口中返回 true?

My code for so far到目前为止我的代码

<script type="text/javascript">
    var elem = document.getElementById("result");
    var bounding = elem.getBoundingClientRect();
        if (bounding.top >= 0 && bounding.left >= 0 && bounding.right <= window.innerWidth && bounding.bottom <= window.innerHeight) {
            alert('in viewport');  
        }
</script>

Based on @Jorg's code, here's the same with the Intersection Observer API , which is a newer way of checking for intersections.基于@Jorg 的代码,这里与Intersection Observer API相同,它是一种较新的检查交叉点的方法。 This will work on all modern browsers ~ 93.5% according to Can I Use根据Can I Use,这将适用于所有现代浏览器 ~ 93.5%

This is set up to make it consider anything that's 50% within the viewport as within the threshold.设置它是为了将视口内 50% 的任何内容视为阈值内。 I made it such a large value so it's easy to see how it works.我将其设置为如此大的值,因此很容易看出它是如何工作的。

As you'll notice with this, the callback is only called at the threshold (after the initial check).正如您会注意到的,回调仅在阈值(在初始检查之后)调用。 So, if you want an accurate intersection percentage, you'll probably want to increase the number of thresholds checked.因此,如果您想要准确的交集百分比,您可能需要增加检查的阈值数量。

 let callback = (entries, observer) => { entries.forEach(entry => { entry.target.style.backgroundColor = entry.isIntersecting ? 'green' : 'red'; entry.target.innerHTML = entry.intersectionRatio; }) } let observer = new IntersectionObserver(callback, { threshold: [0.5] // If 50% of the element is in the screen, we count it! // Can change the thresholds based on your needs. The default is 0 - it'll run only when the element first comes into view }); ['div1', 'div2', 'div3', 'div4'].forEach(d => { const div = document.getElementById(d); if (div) observer.observe(div); })
 html, body { padding: 0; margin: 0; } body { height: 200vh; width: 200vw; } #div1 { position: absolute; left: calc(100vw - 60px - 10px); top: 10px; height: 100px; width: 60px; background-color: red; color: white; } #div2 { position: absolute; left: 20px; top: 10px; height: 50px; width: 60px; background-color: blue; color: white; } #div3 { position: absolute; left: calc(100vw - 260px + 50px); top: max(calc(100vh - 350px + 120px), 120px); height: 350px; width: 260px; background-color: green; color: white; text-align: left; } #div4 { position: absolute; height: 9000px; width: 9000px; color: black; background-color: yellow; }
 <div id="div1"></div> <div id="div2"></div> <div id="div3"></div> <!-- enable this div to see an example of a div LARGER than your viewport. --> <!-- <div id="div4"></div> -->

I guess what you're looking for is the intersection between the element and the viewport?我猜你要找的是元素和视口之间的交集? Meaning, find out how much of the div overlaps with the viewport.意思是,找出有多少 div 与视口重叠。

在此处输入图片说明

Using the function below should tell you, between 0 and 1, how much of the DIV fits inside the viewport.使用下面的函数应该会告诉您,在 0 和 1 之间,有多少 DIV 适合视口。 Be aware though, that the div could also just be larger than the viewport this way, in which case the overlapping area is also less than 1.但请注意,div 也可能只是比视口,在这种情况下,重叠区域也小于 1。

Here is a working example是一个工作示例

const intersection = (r1, r2) => {
  const xOverlap = Math.max(0, Math.min(r1.x + r1.w, r2.x + r2.w) - Math.max(r1.x, r2.x));
  const yOverlap = Math.max(0, Math.min(r1.y + r1.h, r2.y + r2.h) - Math.max(r1.y, r2.y));
  const overlapArea = xOverlap * yOverlap;

  return overlapArea;
}

const percentInView = (div) => {
  const rect = div.getBoundingClientRect();

  const dimension = { x: rect.x, y: rect.y, w: rect.width, h: rect.height };
  const viewport = { x: 0, y: 0, w: window.innerWidth, h: window.innerHeight };
  const divsize = dimension.w * dimension.h;
  const overlap = intersection(dimension, viewport);

  return overlap / divsize;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM