微信号:gh_b206cf608d16

介绍:爆米兔,是一个H5营销在线制作工具.

谈谈IntersectionObserver懒加载

2018-02-10 17:55 小心夹手

编者按:本文由小心夹手发表于掘金,作者已授权分享到奇舞周刊。


概念

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

这是MDN上给的官方概念,不用去管它,我粘出来只是为了显得专业点嘛...

重点看这里监听目标元素与其祖先或视窗交叉状态的手段,其实就是观察一个元素是否在视窗可见。

可以看到,交叉了就是说明当前元素在视窗里,当前就是可见的了。

API

var io = new IntersectionObserver(callback, options)

其实就是一个简单的构造函数。

以上代码会返回一个IntersectionObserver实例,callback是当元素的可见性变化时候的回调函数,options是一些配置项(可选)。

我们使用返回的这个实例来进行一些操作。

io.observe(document.querySelector('img')) 开始观察,接受一个DOM节点对象

io.unobserve(element) 停止观察 接受一个element元素

io.disconnect() 关闭观察器

options

root

用于观察的根元素,默认是浏览器的视口,也可以指定具体元素,指定元素的时候用于观察的元素必须是指定元素的子元素

threshold

用来指定交叉比例,决定什么时候触发回调函数,是一个数组,默认是[0]

const options = {

    root: null,

    threshold: [0, 0.5, 1]

}

var io = new IntersectionObserver(callback, options)

io.observe(document.querySelector('img'))

上面代码,我们指定了交叉比例为0,0.5,1,当观察元素img0%、50%、100%时候就会触发回调函数

rootMargin

用来扩大或者缩小视窗的的大小,使用css的定义方法,10px 10px 30px 20px表示top、right、bottom 和 left的值

const options = {

    root: document.querySelector('.box'),

    threshold: [0, 0.5, 1],

    rootMargin: '30px 100px 20px'

}

为了方便理解,我画了张图,如下

首先我们来看下图上的问题,蓝线是什么呢?他就是咱们定义的root元素,我们添加了rootMargin属性,将视窗的增大了,虚线就是现在的视窗,所以元素现在也就在视窗里面了。

由此可见,root元素只有在rootMargin为空的时候才是绝对的视窗。

说了简单的options,接下来我们看下callback

callback

上面我们说到,当元素的可见性变化时,就会触发callback函数。

callback函数会触发两次,元素进入视窗(开始可见时)和元素离开视窗(开始不可见时)都会触发

var io = new IntersectionObserver((entries)=>{

    console.log(entries)

})


io.observe($0)

以上代码,请在chrome控制台进行调试,这里我使用了$0选择了上一次我审查元素的选择的节点

运行结果如下

我们可以看到callback函数有个entries参数,它是个IntersectionObserverEntry对象数组,接下来我们重点说下IntersectionObserverEntry对象

IntersectionObserverEntry

IntersectionObserverEntry提供观察元素的信息,有七个属性。

boundingClientRect 目标元素的矩形信息 intersectionRatio 相交区域和目标元素的比例值 intersectionRect/boundingClientRect 不可见时小于等于0 intersectionRect 目标元素和视窗(根)相交的矩形信息 可以称为相交区域 isIntersecting 目标元素当前是否可见 Boolean值 可见为true rootBounds 根元素的矩形信息,没有指定根元素就是当前视窗的矩形信息 target 观察的目标元素 time 返回一个记录从IntersectionObserver的时间到交叉被触发的时间的时间戳

上面几个矩形信息的关系如下

👇 划重点

intersectionRatioisIntersecting是用来判断元素是否可见的,押题咯...

懒加载

好了,通过上面一些概念我们大概了解了IntersectionObserver是个什么东西,接下来我们用它来写点代码,写什么呢?没错就是懒加载。

通过IntersectionObserver来实现懒加载,就简单的多了,我们只需要设置回调,判断当前元素是否可见,再进行渲染操作就行了,而不用去关心内部的计算。

主要代码如下

const io = new IntersectionObserver(()=>{ // 实例化 默认基于当前视窗


})


let ings = document.querySelectorAll('[data-src]') // 将图片的真实url设置为data-src src属性为占位图 元素可见时候替换src


function callback(entries){

    entries.forEach((item) => { // 遍历entries数组

        if(item.isIntersecting){ // 当前元素可见

            item.target.src = item.target.dataset.src // 替换src

            io.unobserve(item.target) // 停止观察当前元素 避免不可见时候再次调用callback函数

        }

    })

}


imgs.forEach((item)=>{ // io.observe接受一个DOM元素,添加多个监听 使用forEach

    io.observe(item)

})

本想录制个GIF图,使用Recordlt始终上传不了,谁有好用的GIF图录制软件请推荐个,不胜感激。。

呐,给你花🌹

因篇幅有限,完整代码请阅读原文戳github 😜

⚠️注意

目前IntersectionObserver是一个实验中的功能,请酌情使用。

作者:小心夹手
链接:https://juejin.im/post/5a7973575188257a5911a749
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


奇舞周刊

——————————————————

领略前端技术 阅读奇舞周刊


长按二维码,关注奇舞周刊


 
奇舞周刊 更多文章 汪汪汪,抓紧啦,年前最后一期周刊来啦 AR \/ MR \/ VR \/ XR有什么区别? 调研发行75币的技术可能性 带你玩转技术型炒币 看懂区块链也不是很难嘛!
猜您喜欢 测试工程师的职业规划和职业发展—进阶篇 ​​Appium + Celery实现网页兼容性测试 MySQL 配置文件模板 【855】88岁褚时健:垃圾产品+互联网,简直痴心妄想!(年轻创业者必读) Android 6.0 动态权限