前言
2020年仅剩下最后几天啦,提前预祝各位程序猿和程序媛们元旦快乐,之前有更新过一些基础的内容,根据评论区的反馈,开始更新一些前端进阶的知识,带大家了解一些并非常用但是非常实用的知识,同事看了直呼内行
基础实现滚动加载与懒加载的思路
- 监听浏览器滚动条滚动事件
- 比较滚动scrollTop与元素的clientTop
- 如果元素已经进入视口进行相应的加载与渲染
相信说到滚动加载与懒加载,大家能想到的都是以上的这种思路,基于浏览器滚动事件实现,这种方式实现封装较为困难,需要考虑的因素较多,比如执行时机,元素渲染图片加载都存在异步的考虑情况,性能方面由于滚动会不断执行代码逻辑,需要考虑函数节流等各类封装
IntersectionObserver
基于IntersectionObserver实现滚动加载与懒加载实现会非常简单,并且在性能上会得到很大的提升,可以判断元素是否进入视口,也可以判断元素是否进入自己设置的某个根节点
IntersectionObserver - API
基础用法
var io = new IntersectionObserver(callback, option);
// 开始观察
io.observe(document.getElementById('example'));
// 停止观察
io.unobserve(element);
// 关闭观察器
io.disconnect();
callback是监听之后的回掉
callback函数的参数(res)是一个数组,每个成员都是一个IntersectionObserverEntry对象。举例来说,如果同时有两个被观察的对象的可见性发生变化,res数组就会有两个成员。
option 自定义参数
- time:可见性发生变化的时间,是一个高精度时间戳,单位为毫秒
- target:被观察的目标元素,是一个 DOM 节点对象
- rootBounds:根元素的矩形区域的信息,getBoundingClientRect()方法的返回值,如果没有根元素(即直接相对于视口滚动),则返回null
- boundingClientRect:目标元素的矩形区域的信息
- intersectionRect:目标元素与视口(或根元素)的交叉区域的信息
- intersectionRatio:目标元素的可见比例,即intersectionRect占
- boundingClientRect的比例,完全可见时为1,完全不可见时小于等于0
基于 IntersectionObserver 的全局封装及使用
class Intersection {
constructor(data) { // 构造器
for (let i in data) {
this[i] = data[i]
}
this.selector = document.querySelectorAll(this.dom)[0]
}
// 定义类方法
observer() {
this.io = new IntersectionObserver(
(changes) => {
if(this.callback) this.callback()
changes[0].isIntersecting ? this.next({ changes, cb: this.scrollInView }) : this.next({ changes, cb: this.scrollOutView })
},
{
...this.option
}
);
//开启dom监听
if (this.selector) {
this.io.observe(this.selector);
}
}
next({ changes, cb }) {
if (cb) cb(changes);
}
unobserve() {
if (this.selector) {
this.io.unobserve(this.selector)
}
}
disconnect() {
if (this.selector) {
this.io.disconnect();
}
}
}
const intersection = (data) => {
const io = new Intersection(data)
io.observer()
return io
}
const install = function (Vue, opts = {}) {
Vue.prototype.$intersection = intersection;
};
export default install
使用:
//开启
this.io = this.$intersection({
dom: '#test',
option: {
root: document.querySelector('.container'), //root 如果不传默认为是body
}, //option 可传 intersectionobserver_api 可传的全部入参数
callback: (e) => {
console.log('回掉', e);
},
scrollInView: function (e) {
console.log('元素进入', e, this);
},
scrollOutView: (e) => {
console.log('元素离开', e, this);
},
});
以上就是IntersectionObserver的使用,是不是很简单,快去为项目的滚动进行你的优化吧