JavaScript中判断元素是否在可视区域内
JavaScript中判断元素是否在可视区域内
- 1.有什么应用
- 2.方法1-----使用offsetTop、scrollTop
- 3.方法2-----getBoundingClientRect
- 4.方法3-----Intersection Observer
1.有什么应用
- 懒加载
- 列表的无限滚动
- 计算广告元素的曝光情况
2.方法1-----使用offsetTop、scrollTop
offsetTop、scrollTop属于三大家族的内容,详情见https://blog.csdn.net/fageaaa/article/details/145728760。
思路:元素的offsetTop-页面的scrollTop<=页面的高度
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Title</title>
<style>
.area1,
.area3 {
width: 100%;
height: 1200px;
background-color: aqua;
}
.box {
width: 100%;
height: 100px;
background-color: red;
}
</style>
</head>
<body>
<div class="area1"></div>
<div class="area2 box"></div>
<div class="area3"></div>
<script>
function isInViewPortOfOne(el) {
// 下面是浏览器视口的高度的兼容性写法
const viewPortHeight =
window.innerHeight ||
document.documentElement.clientHeight ||
document.body.clientHeight;
const offsetTop = el.offsetTop;
const scrollTop = document.documentElement.scrollTop;
const top = offsetTop - scrollTop;
//注意这里只是个简略方式,没考虑el的边框
return top <= viewPortHeight && top + el.clientHeight >= 0;
}
let box= document.querySelector(".box");
window.addEventListener("scroll", function () {
if (isInViewPortOfOne(box)) {
console.log("box元素在可视区域内");
} else {
console.log("box元素不在可视区域内");
}
});
</script>
</body>
</html>
3.方法2-----getBoundingClientRect
getBoundingClientRect函数返回值是一个 DOMRect
对象,拥有left
, top
, right
, bottom
, x
, y
, width
, 和 height
属性。详情见https://blog.csdn.net/fageaaa/article/details/145728760。
思路:top
大于等于0;left
大于等于0;right
小于等于viewWidth
;bottom
小于等于viewHeight
function isInViewPort(element) {
const viewWidth = window.innerWidth || document.documentElement.clientWidth;
const viewHeight = window.innerHeight || document.documentElement.clientHeight;
const {
top,
right,
bottom,
left,
} = element.getBoundingClientRect();
return (
top >= 0 &&
left >= 0 &&
right <= viewWidth &&
bottom <= viewHeight
);
}
4.方法3-----Intersection Observer
前面两种方式需要一直监听,就算用了防抖节流也要一直监听(只不过性能会好一点)。所以Intersection Observer
这个方法性能上会更好!!!
浏览器提供了一种异步观察目标元素与祖先元素(或顶级文档的视口)交叉状态变化的方法。IntersectionObserver详细用法见https://blog.csdn.net/fageaaa/article/details/145741778
<head>
<meta charset="UTF-8" />
<title>Title</title>
<style>
.area1,
.area3 {
width: 100%;
height: 1200px;
background-color: aqua;
}
.box {
width: 100%;
height: 100px;
background-color: red;
}
</style>
</head>
<body>
<div class="area1"></div>
<div class="area2 box"></div>
<div class="area3"></div>
<script>
let box = document.querySelector(".box");
//它提供了一种异步观察目标元素与祖先元素(或顶级文档的视口)交叉状态变化的方法。
// 这个API的出现主要是为了高效解决在网页开发中需要频繁判断元素是否进入“视口”(viewport)的问题。
// 相比于传统的依赖scroll事件和getBoundingClientRect方法,Intersection Observer API在性能上有显著的优势
let intersectionObserver = new IntersectionObserver(function (el) {
if (el[0].intersectionRatio <= 0) {
console.log("元素彻底离开可视区");
} else {
console.log("元素进入可视区");
//进入可视区之后,资源已经下载好,就不需要再进行监视了
intersectionObserver.unobserve(box);
}
});
intersectionObserver.observe(box);
</script>
</body>