// 定义相交监视器
var observer = new IntersectionObserver(changes => {
for (const change of changes) {
console.log(change.time); // 发生变化的时间
console.log(change.rootBounds); // 根元素的矩形区域的信息
console.log(change.boundingClientRect); // 目标元素的矩形区域的信息
console.log(change.intersectionRect); // 目标元素与视口(或根元素)的交叉区域的信息
console.log(change.intersectionRatio); // 目标元素与视口(或根元素)的相交比例
console.log(change.target); // 被观察的目标元素
}
}, {});
// 开始观察某个目标元素
observer.observe(target);
// 停止观察某个目标元素
observer.unobserve(target);
// 关闭监视器
observer.disconnect();
使用方式:
const intersectionObserver = new IntersectionObserver(callback, options)
intersectionObserver.observe(target) // 给target注册监听
具体示例:
function ob(target) {
const options = {
root: document.querySelector('#x'), // 根元素。如果为空时,则默认视窗。
rootMargin: '0px', // 根元素的外边距
threshold: 0.25, // number或数组。表示target与root相交的比例,达到比例时则触发回调函数。若指定0,表示只要节点进入可视区域马上触发回调。若指定1,表示节点完全进入可视区域时触发回调(可以用来做无限滚动)
}
const intersectionObserver = new IntersectionObserver((entries, observer)=>{
entries.forEach(entry=>{
// entry.boundingClientRect
// entry.intersectionRatio
// entry.intersectionRect
// entry.isIntersecting
// entry.rootBounds
// entry.target
// entry.time
if(entry.isIntersecting) {
// 若相交了,执行一些业务逻辑,如懒加载
entry.target.setAttribute('src', 'xxx')
...
observer.disconnect()
}
})
}, options)
intersectionObserver.observer(target)
}
window.onload = () => {
const imgs = [...document.querySelector('img')]
imgs.forEach(img=>{
ob(img)
})
}
请留意,你注册的回调函数将会在主线程中被执行。所以该函数执行速度要尽可能的快。如果有一些耗时的操作需要执行,建议使用
Window.requestIdleCallback()
方法。
兼容性: IE球球你做个人吧
相关插件: https://github.com/thebuilder/react-intersection-observer
在需要无限滚动的下方加一个空盒子,这个盒子用来判断内容是否滚动到了底部
<template>
<div class="outter">
<div class="inner"></div>
<div ref="inner" class="test"></div>
</div>
</template>
<script>
export default {
methods: {
createOb(target) {
const options = {
// root: document.documentElement,
rootMargin: "0px 0px 0px 0px", // 如果需要一些提前量,可以设置rootMargin
threshold: [1]
};
const io = new IntersectionObserver((entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
console.log("滚动到底部了");
}
});
}, options);
io.observe(target);
},
},
mounted() {
// console.log(this.$refs.inner);
this.createOb(this.$refs.inner);
},
};
</script>
<style lang="less" scoped>
.outter {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
padding: 32px;
.inner {
height: 2000px;
width: 100%;
background-color: #000;
}
.test {
width: 100%;
height: 0px;
}
}
</style>