图片懒加载,当页面可视区域出现图片元素的时候才加载对应的图片资源(其实就是把src真实的值赋值给他)
VUE
vue这里使用的是自定义指令的方式去实现图片懒加载。
// 这里需要注意 key不要绑定 index, 绑定 id 或者随机数, 不然新增删除图片操作后,图片会出现重复的情况
<img
v-for="(item,index) in arrSrc"
:key="id"
:src="moren"
v-lazy="item"
alt="x"
/>
Vue.directive("lazy", {
inserted(el, binding) {
//定义一个观察器,entries为状态改变元素的数组
let observer = new IntersectionObserver((entries) => {
// 遍历
for (let i of entries) {
// 如果改元素处于可视区
if (i.isIntersecting > 0) {
// 获取该元素
let img = i.target;
// 重新设置src值
img.src = binding.value;
//取消对该元素的观察
observer.unobserve(img);
}
}
});
// 为 img 标签添加一个观察
observer.observe(el);
},
});
上面代码来源于下面的文章,只修改了key值部分
自定义指令文章:blog.csdn.net/luo18312513…
UNI-APP
这里实现的功能是,判断元素是否出现在可视区域内,然后将src赋值替换,所以效果会比较突兀。
正常情况是需要等图片文件加载好了再去替换对应的src的,但是我这里用的是css里面的background-image: url('') 的形式去加载的图片文件,直接用img标签会出现跨域问题,而css内判断不了图片是否加载好了(暂时没发现)。
// 屏幕可视区域变量
windowTemp: {
viewWidth: 0,
viewHeight: 0,
},
// 没有缩略图的情况下,把thumbnailSrc当成src就行
newsList: [{
tips: '',
files: [{
src: item.src, // 原图的路径
thumbnailSrcShow: bgImgLoadingGif, // 加载中的图片路径
name: item.name, // 文件名字
changSrcBoolean: false, // 用于判断是否替换了thumbnailSrcShow
thumbnailSrc: item.thumbnailSrc || item.src // 预防无缩略图thumbnailSrc
}]
}, {
tips: '',
files: []
}]
其实最主要的就是根据所有元素的位置获取范围内的元素有那些,结合自己的数据去进行src的修改
methods: {
// 获取所有元素位置
getElePosition () {
this.$nextTick(() => {
let query = uni.createSelectorQuery();
let imgEle, imgboxEle
// 使用这个方法去获取对应所有元素在页面相对于顶部的位置
query.selectAll('.img-box').boundingClientRect(data => {
imgEle = data
}).exec();
let viewHeightTemp = this.windowTemp.viewHeight
// 现在只能获取到位置数据,获取不到dom数据
// for循环对应的数据,判断是否再屏幕内,再将对应的src赋值过去
// 这里去循环对应范围内的图片数据进行替换
let viewImgEleLength = imgEle.filter(e => e.top < viewHeightTemp).length
let numTemp = 0
// 循环修改,使用for循环是为了能直接
for (let i = 0; i < this.newsList.length; i++) {
let listE = this.newsList[i]
for (let j = 0; j < listE.rhImgs.length; j++) {
let fileE = listE.rhImgs[j]
if (numTemp < viewImgEleLength) {
if (!fileE.changSrcBoolean) {
fileE.changSrcBoolean = true
fileE.thumbnailSrcShow = fileE.thumbnailSrc
}
numTemp++;
} else {
break;
}
}
}
})
},
// 获取屏幕可视区域宽高的方法
getWindowViewSize () {
// 获取手机宽高
let self = this;
uni.getSystemInfo({
success(res) {
// screenHeight 屏幕高度 注意这里获得的高度宽度都是px 需要转换rpx
// windowWidth 可使用窗口宽度
// windowHeight 可使用窗口高度
// screenWidth 屏幕宽度
self.windowTemp.viewHeight = (res.screenHeight * (750 / res.windowWidth)) / 2//窗口高度,将px 转换rpx
self.windowTemp.viewWidth = res.windowWidth
// self.windowTemp.viewHeight = res.windowHeight
}
})
},
}
以上就是全部内容,有优化的地方就是用户滑动屏幕很快的话,还是会和之前一样,所以需要判断当前在界面内的数据有那些(然后进行加载,我这边有缩略图的操作,所以影响不大),因此,这个只是个简单版本的懒加载。
每次写完总感觉文章很垃圾,然而我写了这么多了,哈哈,不理了,冲冲冲。