- 根据元素到窗口顶部距离判断
el.offsetTop - scrollTop <= windowHeight
function isInViewPortOfOne (el) {
// viewPortHeight 兼容所有浏览器写法
const viewPortHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
const offsetTop = el.offsetTop
const scrollTop = document.documentElement.scrollTop
const top = offsetTop - scrollTop
return top <= viewPortHeight
}
补充:小程序提供异步获取元素offsetTop、scrollTop、windowHeight的方法
export const getDom = function (id, obj) {
const query = uni.createSelectorQuery().in(obj);
return new Promise(resolve => {
return query.select(id).boundingClientRect().exec(res => {
resolve(res[0])
});
})
}
export const isInViewport = function (element) {
// 注意:element必须是小程序元素,组件库里不行
// 获取节点位置信息
const top = element.top;
const bottom = element.bottom;
// 获取可视区域的高度
const windowHeight = uni.getSystemInfoSync().windowHeight;
return new Promise((resolve) => {
// 获取页面滚动的位置
uni.createSelectorQuery().selectViewport().scrollOffset(scroll => {
const scrollTop = scroll.scrollTop;
// 判断节点是否在可视区域内
if (bottom > 0 && top - scrollTop < windowHeight) {
// 节点在可视区域内
resolve(true);
} else {
// 节点不在可视区域内
resolve(false);
}
}).exec();
})
}
let viewList = [];
for (let index = 0; index < this.List?.length; index++) {
const item = this.List[index];
const dom = await getDom(`#test${index}`, this);
if (dom) {
const r = await isInViewport(dom);
if (r) viewList.push(item.auctionId)
}
}
console.log('可视区域列表', viewList);
- getBoundingClientRect直接获取元素相对视口的位置(top,left,bottom,left)
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
);
}
- 判断元素是否和视口交叉或进入IntersectionObserver
- 创建观察者
const options = {
threshold: 1.0, //阈值观察范围0-1,0未进入,1完全进入
root:document.querySelector('body') // 必须是目标元素的父级元素
};
const callback = function(entries, observer) {
//这里满足(threshold为1)完全进入目标视口的执行以下内容
entries.forEach(entry => {
entry.time; // 触发的时间
entry.rootBounds; // 根元素的位置矩形,这种情况下为视窗位置
entry.boundingClientRect; // 被观察者的位置举行
entry.intersectionRect; // 重叠区域的位置矩形
entry.intersectionRatio; // 重叠区域占被观察者面积的比例(被观察者不是矩形时也按照矩形计算)
entry.target; // 被观察者
});
};
const observer = new IntersectionObserver(callback, options);//满足options就会执行callback
- 传入观察者开始监听
const target = document.querySelector('.target');
observer.observe(target);
学习参考:
如何判断一个元素是否在可视区域中?