检查元素的一部分是否在视口中
Check if a piece of the element is in viewport
我正在编写 Javascript 代码来检查元素是否在视口中。
但现在我有一个代码,只有当元素在视口中为 100% 时,return 才为真。
有没有办法,例如,如果有 10 个像素 returns 为真,或者元素的百分比...在视口中 return 为真?
到目前为止我的代码
<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>
我猜你要找的是元素和视口之间的交集?意思是,找出有多少 div 与视口重叠。
使用下面的函数应该会告诉您,在 0 和 1 之间,有多少 DIV 适合视口。但请注意,div 也可能只是 比视口大 ,在这种情况下,重叠区域也小于 1.
Here 是一个工作示例
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;
}
根据@Jorg 的代码,这里与 Intersection Observer API, which is a newer way of checking for intersections. This will work on all modern browsers ~ 93.5% according to Can I Use
相同
设置此设置是为了使其将视口内 50% 的任何内容都视为在阈值内。我把它设为这么大的值,所以很容易看出它是如何工作的。
您会注意到,回调仅在达到阈值时调用(初始检查后)。因此,如果您想要准确的交集百分比,您可能需要增加检查的阈值数量。
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> -->
我正在编写 Javascript 代码来检查元素是否在视口中。 但现在我有一个代码,只有当元素在视口中为 100% 时,return 才为真。 有没有办法,例如,如果有 10 个像素 returns 为真,或者元素的百分比...在视口中 return 为真?
到目前为止我的代码
<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>
我猜你要找的是元素和视口之间的交集?意思是,找出有多少 div 与视口重叠。
使用下面的函数应该会告诉您,在 0 和 1 之间,有多少 DIV 适合视口。但请注意,div 也可能只是 比视口大 ,在这种情况下,重叠区域也小于 1.
Here 是一个工作示例
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;
}
根据@Jorg 的代码,这里与 Intersection Observer API, which is a newer way of checking for intersections. This will work on all modern browsers ~ 93.5% according to Can I Use
相同设置此设置是为了使其将视口内 50% 的任何内容都视为在阈值内。我把它设为这么大的值,所以很容易看出它是如何工作的。
您会注意到,回调仅在达到阈值时调用(初始检查后)。因此,如果您想要准确的交集百分比,您可能需要增加检查的阈值数量。
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> -->