可视检测
2023年02月23日
一、IntersectionObserve
1.1 核心
元素即将可见: threshold: 0
元素完全可见: threshold: 1
1.2 语法
- javaScript
- html
- css
const targetDom = document.querySelector(".box");
const intersectionObserverOption = {
threshold: 0,
};
function intersectionObserverCallback(entries, observer) {
entries.forEach((entry) => {
if (entry.isIntersecting) {
observer.unobserve(entry.target);
console.log("元素可见");
}
});
}
const intersectionObserver = new IntersectionObserver(
intersectionObserverCallback,
intersectionObserverOption
);
intersectionObserver.observe(targetDom);
<div class="other"></div>
<div class="box"></div>
.other {
width: 100%;
height: 1800px;
background-color: coral;
}
.box {
width: 100%;
height: 200px;
background-color: cadetblue;
}
二、Scroll、getBoundingClientRect
2.1 核心
元素即将可见
const { top,right,bottom,left } = target.getBoundingClientRect();
return top >= 0 && left >= 0 && right <= viewPortWidth && top <= viewProtHeight;
元素完全可见
const { top,right,bottom,left } = target.getBoundingClientRect();
return top >= 0 && left >= 0 && right <= viewPortWidth && bottom <= viewProtHeight;
2.2 语法
- javaScript
- html
- css
const targetDom = document.querySelector(".box");
function throttle(fn, wait) {
let timer = null;
return function (...args) {
const context = this;
if (!timer) {
timer = setTimeout(() => {
clearTimeout(timer);
timer = null;
fn.apply(context, args);
}, wait);
}
};
}
function isVisible(
boundingClientRect,
viewPortWidth,
viewProtHeight,
threshold
) {
const { top, right, bottom, left } = boundingClientRect;
if (threshold) {
return (
top >= 0 &&
left >= 0 &&
right <= viewPortWidth &&
bottom <= viewProtHeight
);
}
return (
top >= 0 &&
left >= 0 &&
right <= viewPortWidth &&
top <= viewProtHeight
);
}
function handleScroll() {
const boundingClientRect = targetDom.getBoundingClientRect();
const viewPortWidth =
window.innerWidth ||
document.documentElement.clientWidth ||
document.body.clientWidth;
const viewPortHeight =
window.innerHeight ||
document.documentElement.clientHeight ||
document.body.clientHeight;
const visible = isVisible(
boundingClientRect,
viewPortWidth,
viewPortHeight,
true
);
console.log(visible);
}
window.addEventListener("scroll", throttle(handleScroll, 80));
<div class="other"></div>
<div class="box"></div>
.other {
width: 100%;
height: 1800px;
background-color: coral;
}
.box {
width: 100%;
height: 200px;
background-color: cadetblue;
}
三、Scroll、OffsetTop、OffsetHeight
3.1 核心
元素可见: viewPortHeight + viewportScrollTop >= targetDomOffsetTop
3.2 语法
- javaScript
- html
- css
const targetDom = document.querySelector(".box");
function throttle(fn, wait) {
let timer = null;
return function (...args) {
const context = this;
if (!timer) {
timer = setTimeout(() => {
clearTimeout(timer);
timer = null;
fn.apply(context, args);
}, wait);
}
};
}
function isVisible(
viewPortHeight,
viewportScrollTop,
targetDomOffsetTop
) {
return viewPortHeight + viewportScrollTop >= targetDomOffsetTop;
}
function handleScroll() {
const viewPortHeight =
window.innerHeight ||
document.documentElement.clientHeight ||
document.body.clientHeight;
const viewportScrollTop =
document.documentElement.scrollTop ||
window.pageYOffset ||
document.body.scrollTop;
const targetOffsetTop = targetDom?.offsetTop || 0;
const visible = isVisible(
viewPortHeight,
viewportScrollTop,
targetOffsetTop
);
console.log(visible);
}
window.addEventListener("scroll", throttle(handleScroll,80));
<div class="other"></div>
<div class="box"></div>
.other {
width: 100%;
height: 1800px;
background-color: coral;
}
.box {
width: 100%;
height: 200px;
background-color: cadetblue;
}