前言
本文是把element-ui的image组件的懒加载方式,单拎出来给大家讲解,学习一下element是如何做图片懒加载的。这里面需要你掌握一点vue基础知识,不过不会也没事关系不大。
代码
这是element-ui,image组件提供的参数是否要启动懒加载,不熟悉image组件的用法的人建议去看一下,我先提一嘴用法,就是每个组件只对应一张图片,记住这个就行。好了我们根据lazy这个线索去看,用注释的方式讲解。
mounted() {
//如果lazy为true那么执行addLazyLoadListener这个方法。
if (this.lazy) {
this.addLazyLoadListener();
} else {
//不用管,没用懒加载直接加载图片的方法
this.loadImage();
}
},
addLazyLoadListener() {
//正行代码不用管,这是检测是否是服务器环境
if (this.$isServer) return;
//scrollContainer 开启懒加载后,监听 scroll 事件的容器(官方文档的解释),因为你要提供要监听scroll事件的dom吗,不懂先往后看。
const { scrollContainer } = this;
let _scrollContainer = null;
//这里就是为了让使用改组建的人方便,你提供类名,ID我就去获取dom,你要直接提供dom,我就直接用,就这意思,如果你啥也没给我,那我就在挂在改组件的$el元素上找第一个overflow:auto的元素,这文档都说了啊。
if (isHtmlElement(scrollContainer)) {
_scrollContainer = scrollContainer;
} else if (isString(scrollContainer)) {
_scrollContainer = document.querySelector(scrollContainer);
} else {
_scrollContainer = getScrollContainer(this.$el);
}
//如果这个dom元素存在,继续往下走
if (_scrollContainer) {
this._scrollContainer = _scrollContainer;
//throttle节流方法,element是引入的throttle-debounce的一个库,下面我会给地址,handleLazyLoad监听到时间的回调方法,下面会给具体的方法
this._lazyLoadHandler = throttle(200, this.handleLazyLoad);
//on是封装的方法,挂监听事件
on(_scrollContainer, 'scroll', this._lazyLoadHandler);
//初始化执行一次
this.handleLazyLoad();
}
},
throttle地址。
isInContainer注意这个方法,最核心的,element-ui通过元素是否在可视区域内来判断是否要加载图片
handleLazyLoad() {
if (isInContainer(this.$el, this._scrollContainer)) {
this.show = true;
this.removeLazyLoadListener();
}
},
export const isInContainer = (el, container) => {
if (isServer || !el || !container) return false;
//getBoundingClientRect这个api下面会给网址,element就是通过这个api来判断dom是否在可视内容区中,
const elRect = el.getBoundingClientRect();
let containerRect;
//如果是其中里面的一项则,把元素做为视口去计算
if ([window, document, document.documentElement, null, undefined].includes(container)) {
containerRect = {
top: 0,
right: window.innerWidth,
bottom: window.innerHeight,
left: 0
};
} else {
containerRect = container.getBoundingClientRect();
}
//最后通过这个去比较,元素是否在可视区域内
return elRect.top < containerRect.bottom &&
elRect.bottom > containerRect.top &&
elRect.right > containerRect.left &&
elRect.left < containerRect.right;
};
getBoundingClientRectAPI,
返回值类型:
elRect.top:元素上边到视窗上边的距离;
elRect.right:元素右边到视窗左边的距离;
elRect.bottom:元素下边到视窗上边的距离;
elRect.left:元素左边到视窗左边的距离;
总结
今天先写这么多,后面有时间我再把大图预览还有其它的一些逻辑写写。