这里是详细MDN介绍:Intersection Observer API 允许你配置一个回调函数,每当目标(target)元素与设备视窗或者其他指定元素发生交集的时候执行。设备视窗或者其他元素我们称它为根元素或根(root)。通常,您需要关注文档最接近的可滚动祖先元素的交集更改,如果元素不是可滚动元素的后代,则默认为设备视窗。如果要观察相对于根(root)元素的交集,请指定根(root)元素为null。
请先忍忍,例子里有动图介绍!
具体用法
1.构造函数
const observer = new IntersectionObserver(callback, options)
Intersection observer
通过js计算属性来实现
记得以前写懒加载时,用的是一个(名字不重要)的第三方库,基本思想是:通过在onScroll事件里计算图片的offsetTop和clientHeight来判断图片是否到达了可展示区域,再替换img的src来加载正确的图片地址。
其实大部分和滚动相关交互的实现思路都和上述懒加载的实现差不多:通过在onScroll里对一些计算属性值的判断来做一些操作。这种方法不好的地方是代码里充斥着大量的offsetTop,clientHeight等取值计算,一来看着不舒服,二来这种计算属性的计算会造成浏览器的重绘,对性能上有一定的影响。
Intersection observer小利器
Intersection observer :交叉观察者,顾名思义,他是一个判断两个元素是否发生交叉的观察者!
这里是详细MDN介绍:Intersection Observer API 允许你配置一个回调函数,每当目标(target)元素与设备视窗或者其他指定元素发生交集的时候执行。设备视窗或者其他元素我们称它为根元素或根(root)。通常,您需要关注文档最接近的可滚动祖先元素的交集更改,如果元素不是可滚动元素的后代,则默认为设备视窗。如果要观察相对于根(root)元素的交集,请指定根(root)元素为
null
。请先忍忍,例子里有动图介绍!
具体用法
1.构造函数
2.options
传递到
IntersectionObserver()
构造函数的options
对象,允许你控制调用观察者的回调环境,具体配置有:root
接受一个dom,作为发生交叉的视图窗口,必须是目标元素的父级元素。如果未指定或者为null,则默认为浏览器的视窗。
rootMargin
root元素的外边距,可以扩大/缩小视窗的交集范围。用法和css中的margin属性一样,比如:
“10px 120px 30px -60px”(top, right, bottom, left)
,正数时是往外扩张,负数时是往里缩放。threshold
接受一个number或者一个number数组(number的值在0 - 1中间)。当目标元素和root元素相交程度的百分比达到指定值时,构造函数里注册的回调函数将会被执行。比如设置threshold:0.5,那么当目标元素在root中的可视区域占自身50%时,触发回调函数,如果你想可见程度每增加/减少25%时就触发一次回调,那么应该设置成:threshold:[0, 0.25, 0.5, 0.75, 1]。默认是0。
3.目标(target)元素
构建后为每个观察者配置一个对象
4.callback
传递到
IntersectionObserver()
构造函数的回调函数,当达到IntersectionObserver指定的threshold时,触发回调。回调接受IntersectionObserverEntery
对象和观察者列表。5.常用方法
例子
监听一个class="box"的元素是否进入视窗
效果如下:
监听多个class="box"的元素是否进入视窗
为什么下面打印出来的length是1呢?entries返回的是当前正在发生交叉的目标集合。上面是大家一起发生交叉,每次返回的集合长度都是3,下面是大家轮流发生交叉,每次返回的集合长度都是1。
实际应用
相关例子的代码已上传至intersectionDemo
1.懒加载
用Intersection observer实现懒加载代码优雅多了,你只需将图片设置为目标函数。
假设html为:
js相关代码为:
效果为: (啊,文件太大被吞了,可通过运行demo里的例子自己看下哈,不过我拍的照片可真好看呀。)
2.列表加载数据
移动端滚动列表加载数据常见case是:下拉到页尾时继续加载下一页数据,这个也可以用Intersection observer来实现:
效果如下:
只是个简单的例子,每次到底部补充数据替换dom,所以替换dom时页面会有点晃动,如果你用react/vue这种牛逼哄哄的框架就不会有这种问题啦
(啊,文件依旧太大被吞了,可通过运行demo里的例子自己看下哈,不过我拍的照片确实好看呢。)
当然你可以把1和2的例子结合在一起,做一个底部请求数据同时懒加载的列表页。
3.模拟position: sticky实现吸顶效果
效果如下: (终于有个可以上传的例子了!,我拍的照片是不是很好看!)
兼容性
IE不兼容,不过有官方的polyfill
最后
更多的一些例子请移步参考:intersectionDemo,感觉还能做很多其他好玩的事情,欢迎大家补充~