怎么对我们的图片进行懒加载呢
整理一下
这次是vue项目
思路:
图片懒加载的原理只加载可视区域的图片,那么明显的需要判断图片距离顶部的距离。
借助于DOM.getBoundingClientRect() 拿到我们的元素的距离可视区域顶部的距离 ,与我们的可视区域高度作对比即可知道我们的元素是不是在可视区域内。
解决了,判定是否存在于可视区域的问题,那么下一步是具体怎么对图片进行操作。
这里借助于一个data-src 我们为组件中想要进行懒加载的图片设置自定义属性,先不使用 img 的src加载想要的图片, 让src先加载一个统一的资源未加载时展示的图片。
我们通过为页面添加滚动事件 来进一步处理,在滚动时我们需要拿到图片的dom,通过为src赋值,可以达成懒加载效果。
当然直接赋值会出现一种,“挤牙膏”方式的加载,图片会一点一点被加载出来,感觉用户体验不是很好,那么介绍另一种优雅一些的方式。
在我们需要操作 img(DOM)的地方,我们借助于 new Image().src 先把资源加载的浏览器上,通过 监听new Image()的 onload方法来在图片资源加载完成时,我们用这个new Image的src 赋值给 真正的img(DOM)的src,图片就会迅速替换
这样懒加载的基本思路算是完成了。
当然,我们开始时还需要考虑,在页面加载的时候我们动态的去获取组件中的img集成到一个数组中去,数组的格式为
@dom: 真正的img dom;@url:从data-url中获取的url;@status:type String;每一个dom的状态,包含pending/ resolve 两个状态
[ { dom, url, status } ]
类似这样的格式。
上个代码 封装到一个js文件去了
export default {
addLazyLoad: (list = [], loadImg) =>{
let flag = true;
loadImg(list); //首次加载即渲染一次
return function (time = 500, distance = 100) {
document.body.onscroll = () => {
if (!list.length) document.body.onscroll = null;
let top = document.documentElement.scrollTop || document.body.scrollTop; //为滚动时的位置
if (flag) {
flag = false;
let timer = setTimeout(() => {
// 节流
let scroll_top = document.documentElement.scrollTop || document.body.scrollTop; //滚动以后的位置
let scroll_distance = scroll_top - top; // 滚动距离
if (scroll_distance > distance) { // 但距离大于某个值 那么开始执行加载图片
loadImg(list);
}
flag = true; // 重新允许监听懒加载
clearTimeout(timer); // 执行完毕销毁定时器
}, time);
}
};
}
},
loadImg: (lazyImgs)=>{ //传入一个有图片dom的数组
lazyImgs = lazyImgs.filter(i => i.status === 'pending');
for (let i = 0, len = lazyImgs.length; i < len; i++) {
let pos = lazyImgs[i].dom.getBoundingClientRect();
// 只要这个距离小于可视区的高度那么说明就在可视区域内 那么就加载
if (pos.top < window.innerHeight) {
let img = new Image();
img.src = lazyImgs[i].url;
img.onload = () => {
lazyImgs[i].dom.src = img.src;
lazyImgs[i].status = 'resolve';
}
}
}
}
}
至于 怎么获取页面内的dom 那么你想控制那一块懒加载那么就去获取装载那一块的dom到数组中去 传参即可