小知识,大挑战!本文正在参与“程序员必备小知识”创作活动
本文同时参与「掘力星计划」,赢取创作大礼包,挑战创作激励金
前言
大家好,目前为止,六大常用自定义指令已经接近尾声了。那么今天即将出场也是最后一个隆重出场的便是我们的图片懒加载的自定义指令v-lazyload了。
先来简单介绍下,为什么要用图片懒加载而不是直接加载?小伙伴们应该都知道,在前端中向引入外部css文件,JavaScript文件以及一些图片资源等等都是需要发送单独的http请求的,而http请求多了势必会影响到页面的性能,如果一个页面有大量的图片需要加载,如果不采用懒加载的话,就会需要大量的http请求从而占用了页面其它资源的正常请求进而就会影响到了页面的性能,这绝对是不可取的。因此图片的懒加载就因运而生了。
虽然大量的http请求是不可避免的,但是我们可以让它们分批分时去请求而不是一次性的全部请求,这也是懒加载的核心所在。懒加载最大的的有点就是可以让图片最后请求,或者说是需要展示的时候再请求,不展示就不请求,这样一来必然就节省了很多的http占用。比如说像京东、淘宝这类电商网站,当我们搜索一件商品时,会搜出很多很多,这时候我们就需要向下拖动滚动条来筛选适合我们想要的商品,而这个过程就利用了图片懒加载的技术,也就是说当前屏幕中呈现在我们面前的图片会优先展示出来,而那些隐藏的图片是不会去请求的而是随着滚动条的向下滚动,图片即将要出现在屏幕中时在去请求。
下面我们就来分析一下如何实现一个图片懒加载的自定义指令
思路分析
- 这里要实现一个图片懒加载的自定义指令,我们还需要借助浏览器为我们提供的一个原生的构造函数:IntersectionObserver,它可以用来监听元素是否进入了设备的可视区域之内。因此我们就利用它的这一特点来控制是否需要进行图片的加载。关于IntersectionObserver这里不做过多的介绍,仅仅拿来使用。
- IntersectionObserver需要两个参数,一个是回调函数,一个是配置对象。其中配置对象中有个threshold属性(其值为0~1)可以用来控制什么时候来触发回调函数。比如元素刚刚出现在视口或者元素完全出现在视口等等.
- 在IntersectionObserver的回调函数中我们需要解析出两个值target和isIntersecting,target就是要监听的元素对象,而isIntersecting是一个布尔值用于标识是否达到了视口条件。
- 一般情况下,我们的img元素不会直接放在文档流中,而是将其包裹在div或者是li中,我们需要绑定指令的也不是直接给img元素而是它的父元素div或li,因此我们要监听的也是父元素div或者li,即我们在回调函数中解析出来的target应该是img的父元素。所以这里还需要通过父元素获取到真正的img元素,然后把真正的图片地址赋值给img的src属性从而实现图片的加载展示。
- 在自定义指令的mounted函数中只需要两句代码,一个是接收指令传过来的图片的真实路径,并把它保存于元素el的自定义属性中,便于后续IntersectionObserver使用。另一句则是将元素el通过IntersectionObserver的observe实现监听
- 这么说下来小伙伴们可能还是云里雾里,下面直接上代码
懒加载指令代码
<div v-lazyload="./xxx.jpg"><img src=""/></div>
<div v-lazyload="./xxx.jpg"><img src=""/></div>
<div v-lazyload="./xxx.jpg"><img src=""/></div>
<div v-lazyload="./xxx.jpg"><img src=""/></div>
const ob_config = {
threshold: [1]//当图片完全出现在视口中时在加载
};
const ob = new IntersectionObserver((entries)=>{
entries.forEach(item=>{
let {target, isIntersecting} = item;//解析出监听元素对象(div)和标识
if(!isIntersecting) return;
let imgBox = target.querySelector('img');//获取真实的img元素
if(!imgBox) return;
imgBox.src = target.$src;//通过监听元素的自定义属性拿到真实的图片路径并绑定给img的src属性
imgBox.style.opacity = 1;//让图片显示
ob.unobserve(target);//解除监听
});
}, ob_config);
const app = createApp();
app.directive('lazyload', {
mounted(el, binding){
let imgBox = el.querySelector('img');
if(!imgBox) return;
imgBox.src = '';
//以上3句代码完全可以省略
//下面的2句可以放在同一样式中
imgBox.style.opacity = 0;//不显示图片元素
imgBox.style.transition = 'opacity .3s';//设置过度效果
//以下两句才是关键
el.$src = binding.value;//接收指令值并绑定给el的自定义属性$src上
ob.observe(el);//监听el
}
});
总结
一个简单的图片懒加载就这么实现了,听上去很复杂其实实现起来很简单。
到此,常用的六大常用有好玩的自定义指令就已经全部学完了,有不懂的小伙伴欢迎评论留言
如果觉得还不错的小伙伴也欢迎点赞留言加关注哦!