方法一、通过元素的位置信息和滚动条滚动的高度来判断
前置知识
- clientWidth: 元素的内容区域宽度加上左右内边距宽度。
- offsetTop: 元素的上外边框至包含元素的上内边框之间的像素距离。
- document.documentElement.clientHeight: 获取视口高度(不包含滚动条的隐藏高度)。
- document.documentElement.scrollHeight:获取浏览器窗口的总高度(包含滚动条的隐藏高度)。
- document.documentElement.scrollTop: 获取滚动条滚动的高度
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.div {
height: 2000px;
}
p {
height: 200px;
color: white;
background-color: blueviolet;
}
</style>
</head>
<body>
<!-- 1. 通过元素的位置信息和滚动条滚动的高度来判断 -->
<div class="div"></div>
<p>我出现啦</p>
<script>
function isContain(dom) {
// 获取可视窗口的高度- 兼容写法
const screenHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
// 获取滚动条滚动的高度
const scrollTop = document.documentElement.scrollTop;
// 获取元素偏移的高度,就是距离可视窗口的偏移量
const offsetTop = dom.offsetTop;
return offsetTop - scrollTop <= screenHeight;
}
const p = document.querySelector('p')
window.onscroll = () => {
if (isContain(p)) {
document.body.style.backgroundColor = 'blue'
} else {
document.body.style.backgroundColor = 'skyblue'
}
}
</script>
</body>
</html>
方法二、通过getBoundingClientRect方法来获取元素的位置信息,然后加以判断
前置知识
-
getBoundingClientRect方法: DOM对象的一个方法,返回一个DOMRect对象。
-
详解:https://blog.csdn.net/weixin_61597234/article/details/134878221
-
如果想要判断子元素是否在可视区域内,只需要:
- top >= 0
- left >= 0
- bottom <= 视口高度
- right <= 视口宽度
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.div {
height: 2000px;
}
p {
height: 200px;
color: white;
background-color: blueviolet;
}
</style>
</head>
<body>
<!-- 2. 通过getBoundingClientRect方法来获取元素的位置信息,然后加以判断 -->
<div class="div"></div>
<p>我出现啦</p>
<script>
function isContain(dom) {
const totalHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
const totalWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
// 当滚动条滚动时,top、left、bottom、right时刻会发生改变
const { top, right, bottom, left } = dom.getBoundingClientRect();
return left >= 0 && top >= 0 && right <= totalWidth && bottom <= totalHeight;
}
const p = document.querySelector('p')
window.onscroll = () => {
if (isContain(p)) {
document.body.style.backgroundColor = 'red'
} else {
document.body.style.backgroundColor = 'green'
}
}
</script>
</body>
</html>
方法三、通过交叉检查器:Intersection Observer 来实现监听(推荐)
前置知识
MDN: https://developer.mozilla.org/zh-CN/docs/Web/API/Intersection_Observer_API
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.div {
height: 2000px;
}
p {
height: 200px;
color: white;
background-color: blueviolet;
}
</style>
</head>
<body>
<!-- 3. 通过交叉检查器:Intersection Observer 来实现监听 -->
<div class="div"></div>
<p>我出现啦</p>
<script>
const p = document.querySelector('p')
const observer = new IntersectionObserver(entries => {
if (entries[0].isIntersecting) {
document.body.style.backgroundColor = 'skyblue'
} else {
document.body.style.backgroundColor = 'orange'
}
}, {
threshold: .2, // 表示当子元素和父元素覆盖多少时触发回调函数。
});
observer.observe(p)
</script>
</body>
</html>