懒加载之IntersectionObserver API

1,781 阅读4分钟

前言:关于懒加载的使用之前是使用监听scroll事件来计算,这种方法性能不好。查了资料,发现了IntersectionObserver API,就总结记录下。

1. 什么是懒加载

懒加载(Load On Demand)是一种独特而又强大的数据获取方法,它能够在用户滚动页面的时候自动获取更多的数据,而新得到的数据不会影响原有数据的显示,同时最大程度上减少服务器端的资源耗用。 百度百科

2. 为什么要引入懒加载

懒加载(LazyLoad)是前端优化的一种有效方式,节省了系统响应时间,提升了系统性能,非常具有利用价值。

3. IntersectionObserver API

开发中经常会遇到判断某个元素是否进入了"视口"(viewport),移动端尤为常见。

一般我们的实现方法是,监听到scroll事件后,调用目标元素的getBoundingClientRect()方法,得到它对应于视口左上角的坐标,再判断是否在视口之内。这种方法的缺点是,频繁的监听scroll事件执行回调函数,计算量大,影响性能。

今天来介绍:IntersectionObserver API

IntersectionObserver接口为开发者提供了一种可以异步监听目标元素与其祖先或视窗(viewport)交叉状态的手段。祖先元素与视窗(viewport)被称为根(root)。

3.1 API

var io = new IntersectionObserver(callback, option);

IntersectionObserver是浏览器原生提供的构造函数,接受两个参数:callback是被监听元素的可见性变化时的回调函数,option是配置对象(该参数可选)

3.2 具体使用

实例io的observe方法指定监听哪个dom节点。

io.observe(document.querySelector('img'))  开始观察,接受一个DOM节点对象
io.unobserve(element)   停止观察 接受一个element元素
io.disconnect() 关闭观察器

3.3 callback 参数

目标元素的可见性变化时,就会调用观察器的回调函数callback。

var io = new IntersectionObserver(  entries => {   
 console.log(entries); 
});

callback函数的参数(entries)是一个数组,每个成员都是一个IntersectionObserverEntry对象。

3.3.1 IntersectionObserverEntry对象

IntersectionObserverEntry对象提供目标元素的信息,一共有六个属性。

time:可见性发生变化的时间,是一个高精度时间戳,单位为毫秒
target:被观察的目标元素,是一个 DOM 节点对象
rootBounds:根元素的矩形区域的信息,getBoundingClientRect()方法的返回值,如果没有根元素(即直接相对于视口滚动),则返回null
boundingClientRect:目标元素的矩形区域的信息
intersectionRect:目标元素与视口(或根元素)的交叉区域的信息
intersectionRatio:目标元素的可见比例,即intersectionRect占boundingClientRect的比例,完全可见时为1,完全不可见时小于等于0

4. Option 对象

IntersectionObserver构造函数的第二个参数是一个配置对象。它可以设置以下属性。

4.1 threshold 属性

threshold属性决定了什么时候触发回调函数。它是一个数组,每个成员都是一个门槛值,默认为[0],即交叉比例(intersectionRatio)达到0时触发回调函数。

const options = {   
 root: null,    
 threshold: [0, 0.5]
}
var io = new IntersectionObserver(callback, options)io.observe(document.querySelector('img'))

上面例子表示img展示0和50%的触发回调函数。

4.2 root 属性,rootMargin 属性

IntersectionObserver API 支持容器内滚动。root属性指定目标元素所在的容器节点(即根元素)。注意,容器元素必须是目标元素的祖先节点。

var options = {  
 root: document.querySelector('.root'),  
 rootMargin: "50px 40px" 
};
var observer = new IntersectionObserver(  callback,  options);

上面例子确定了根元素的范围,即是观察元素的监听范围。

5. IntersectionObserver API 是异步的,不随着目标元素的滚动同步触发。

工作中运用: 1、上拉加载 2、图片懒加载 ......

另外,图片懒加载也可以使用我们常用的第二种方法,通过clientHeight,scrollTop,offsetTop等以及监听滚动scroll事件计算目标元素位置,从而替换img的src属性。

//主要逻辑部分如下:
<script>
    function lazyload() {
        var images = document.getElementsByTagName('img');
        var length = images.length;
        return function() {
            var seeHeight = document.documentElement.clientHeight;
            var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
            for(let i = 0; i < len; i++) {
                if(images[i].offsetTop < seeHeight + scrollTop) {
                   if(images[i].getAttribute('src') === '默认地址') {
                      images[i].src = images[i].getAttribute('data-src');
                    }
                }
            }
        }
    }
 </script>              

结语:

一点一滴积累,一步一步前进。分享工作中遇到的问题和日常琐事,欢迎关注公众号:南山zwl。

GitHub:github.com/wlzhangYes

参考文章:

www.ruanyifeng.com/blog/2016/1…