前端开发,对于Observer,应该很熟悉,早之前,刚开始开发前端的时候,老是看群里大佬说没有被Observer到,觉得老高大上了。简单解释就是观察者,也就是说没有被监听到,其实跟订阅发布或者观察者模式有点类似。
提供了一种异步观察目标元素与其祖先元素或顶级文档视窗(viewport)交叉状态的方法。祖先元素与视窗(viewport)被称为根(root)。
简单来说就是监听元素出现在根元素,IntersectionObserver接收两个参数,第一个是回调,第二个是配置项:
new IntersectionObserver(handler, options)
let observer = new IntersectionObserver((entries, observer) => {
}, {
root: null,
rootMargin: '0px',
threshold: [0],
});
handler函数有两个参数,一个是监听对象的数组,一个是当前实例
options有三个参数:
root:指定根元素,如果没有指定是默认document
rootMargin:默认0px,比如一个div宽高300px,设置50px的rootMargin,那么就是监听这个div上下左右都减去50px。
threshold:线性升序排序,就是出现到这个元素的百分比的时候就触发回调函数。
然后监听:
observer.observe(document.querySelector('#test1'))
总共有四个方法:
observe()开始监听一个元素,可以同时监听多个
disconnect()停止监听所有
takeRecords()返回所有观察目标的对象数组
unobserve()停止监听特定目标
看一个简单的效果:
看看代码:
let observer = new IntersectionObserver((entries, observer) => {
let percent = entries[0].intersectionRatio * 100;
document.getElementById('percent').innerText = parseInt(percent) + '%'
}, {
root: null,
rootMargin: '0px',
threshold: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1],
});
observer.observe(document.getElementById('test'))
百分比会有一些误差,没办法真正在百分之10这样的时候触发回调,因为IntersectionObserver API 是异步的,不随着目标元素的滚动同步触发。这个观察器的优先级非常低,只在其他任务执行完,浏览器有了空闲才会执行。
运用这个api,可以很容易实现懒加载,还有视频往上滑动就暂停,无限滚动等。而且使用这个api最大的优势就是对性能的友好了。当然,兼容性却是一个需要考虑的因素。
最后有个问题,我不知道为什么我初始化之后,一监听就会先进入回调,这个问题没有找到答案。有个群友说根据rxjs的解释,跟热观察和冷观察会有关系,不知道这个api是否是热观察,如果是热观察,那么初始化就会监听。