小程序中的瀑布流是什么意思

这篇文章将为大家详细讲解有关小程序中的瀑布流是什么意思,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

瀑布流是一种很常见的网页布局,视觉表现为参差不齐的多栏布局,是一种时下很流行的布局形式,最近在写小程序恰好也碰到了,想了几种不同的实现方法,接下来就来一起看看具体的实现方法(所用的方法中用的例子都是两栏的布局)。

等高的瀑布流

等高的瀑布流顾名思义就是瀑布流里的单个盒子的高度都是一样的,这种形式的瀑布流实现起来也比较简单,因为不涉及到盒子高度的计算,举个例子:

<viewclass="fall">
<viewwx:for="{{list}}"class="fall-item"></view>
</view>
Page({
data:{
list:[]
},
onLoad(){
letimages=[]
for(leti=0;i<10;i++){
images.push({
url:'test'
})
}
this.setData({
list:images
})
}
})
.fall{
display:flex;
flex-wrap:wrap;
background-color:#f7f7f7;
}
.fall-item{
width:330rpx;
height:330rpx;
margin-top:30rpx;
margin-left:30rpx;
background-color:aquamarine;
}

为了方便,例子中的盒子内容并没有使用图片,而是使用了色块代替,等高瀑布流的实现可以直接通过flex布局实现,如例子所示,直接用flex布局,允许换行,设置好瀑布流里中每一个盒子的宽高,就能实现简单的实现两栏瀑布流布局

不等高瀑布流

不等高瀑布流是更为常见的形式,不等高瀑布流涉及到列高的计算,由于每个盒子的高度不一样,因此需要每一列的列高都要记录、比较,将下一个盒子插入高度矮的一列,接下来就来看看不等高瀑布流的实现方式

已知盒子高度

一般瀑布流里展示的都是图片,这种情况指的是服务端会返给前端要展示的图片的宽高,这种情况下相对也比较简单,因为服务端会返回图片的宽高,前端只需要计算一下列高,将下一张图片插入矮的那里一列就可以,举个例子:

<viewclass="fall">
<viewwx:for="{{list}}"wx:for-index="idx"wx:for-item="column"class="fall-column">
<viewclass="fall-column-item"wx:for="{{column}}"wx:for-index="i"wx:for-item="item"style="height:{{item.showHeight}}rpx"></view>
</view>
</view>
.fall{
display:flex;
background-color:#f7f7f7;
}

.fall-column{
display:flex;
flex-direction:column;
margin-left:30rpx;
}

.fall-column-item{
width:330rpx;
margin-top:30rpx;
background-color:aquamarine;
}
Page({
data:{
images:[{
width:360,
height:540
},{
width:480,
height:540
},{
width:540,
height:720
},{
width:720,
height:960
},{
width:540,
height:960
},{
width:360,
height:720
},{
width:360,
height:960
},{
width:540,
height:540
},{
width:540,
height:1440
},{
width:960,
height:1440
}],
heightArr:[],
list:[],
col:2
},
onLoad(){
this.initData(2)
},
initData(col){
letimages=[]
letscale=2
//模拟图片宽高
for(leti=0;i<10;i++){
letimage=this.data.images[Math.floor(Math.random()*10)]
images.push(image)
}
for(letiinimages){
letheight=165/images[i].width*images[i].height*scale
images[i].showHeight=height
//第一行的两个盒子
if(i<col){
this.data.list.push([images[i]])
this.data.heightArr.push(height)
}else{
//选出高度较矮的一列的索引
letminHeight=Math.min.apply(null,this.data.heightArr)
letminHeightIndex=this.data.heightArr.indexOf(minHeight)
this.data.list[minHeightIndex].push(images[i])
this.data.heightArr[minHeightIndex]+=height
}
}
this.setData({
list:this.data.list
})
},
onReachBottom(){
this.initData(0)
}
})

上例中为了方便也是用色块模拟了图片,在js中模拟了10张图片的宽高,每次从中随机取10张图片,定义了两列,每次计算一下每列的高度,将图片插入矮的那一列,然后将记录用高度数组,将图片的高度累加,实现起来也很简单

未知盒子高度

未知盒子高度的情况下,我们要怎么做呢?

wx.getImageInfo

第一种办法就是通过wx.getImageInfo可以获取到图片宽高信息,举个例子:

<viewclass="fall">
<viewclass="fall-column"wx:for="{{list}}"wx:for-index="idx"wx:for-item="column"wx:key="{{idx}}">
<viewclass="fall-column-item"wx:for="{{column}}"wx:for-index="i"wx:key="{{i}}"wx:for-item="item">
<imageclass="fall-column-item-img"src="{{item.cover}}"mode="widthFix"/>
</view>
</view>
</view>
.fall{
display:flex;
background-color:#f7f7f7;
}

.fall-column{
display:flex;
flex-direction:column;
margin-left:30rpx;
}

.fall-column-item{
margin-top:30rpx;
line-height:0;
}

.fall-column-item-img{
width:330rpx;
}
importapifrom'../../api/index'
Page({
data:{
list:[],
heightArr:[]
},
asynconLoad(){
let{results}=awaitapi.fetchImages()
letcol=2
for(letiinresults){
results[i].cover=results[i].imageUrl
//获取图片信息
letinfo=awaitthis.loadImage(results[i].cover)
results[i].height=165/info.width*info.height
if(i<col){
this.data.list.push([results[i]])
this.data.heightArr.push(results[i].height)
}else{
letminHeight=Math.min.apply(null,this.data.heightArr)
letminHeightIndex=this.data.heightArr.indexOf(minHeight)
this.data.list[minHeightIndex].push(results[i])
this.data.heightArr[minHeightIndex]+=results[i].height
}
}
this.setData({
list:this.data.list
})
},
loadImage(cover){
returnnewPromise(resolve=>{
wx.getImageInfo({
src:cover,
success:(res)=>{
resolve(res)
}
})
})
}
})

当服务端没有返回图片的宽高时,可以直接通过wx.getImageInfo()获取到图片的信息,这里为了不打乱服务返回时的图片顺序,特意将这个单独用Promise封了一层,就是为了图片加载完一张再获取下一张,但是当图片比较大的时候就会导致加载的时间会很长,会有长时间的白屏:小程序中的瀑布流是什么意思

这是因为wx.getImageInfo()获取图片信息的时候会先将图片下载下来,然后才能获取图片信息,这就导致时间会比较长,但是如果不需要图片加载顺序时可以考虑直接并行加载,不等上一张图片加载完就加载下一张,这样就能更快的展现

wx.getImageInfo优化

既然图片加载获取信息时间比较长,那考虑是否可以加上一个默认的图片,这样用户能在第一时间看到有内容展示,图片信息拿到后再将图片显示出来,举个例子:

<viewclass="fall">
<viewclass="fall-column"wx:for="{{list}}"wx:for-index="idx"wx:for-item="column"wx:key="{{idx}}">
<viewclass="fall-column-item"wx:for="{{column}}"wx:for-index="i"wx:for-item="item"wx:key="{{i}}">
<imageclass="fall-column-item-img"src="{{item.cover}}"mode="widthFix"/>
</view>
</view>
</view>
.fall{
display:flex;
background-color:#f7f7f7;
}

.fall-column{
display:flex;
flex-direction:column;
margin-left:30rpx;
}

.fall-column-item{
position:relative;
margin-top:30rpx;
line-height:0;
background-color:#ccc;
}

.fall-column-item::after{
content:'加载中';
position:absolute;
top:50%;
left:50%;
transform:translate(-50%,-50%);
display:inline-block;
color:#666;
}

.fall-column-item-img{
position:relative;
width:330rpx;
z-index:1;
}
importapifrom'../../api/index'
Page({
data:{
list:[],
heightArr:[]
},
asynconLoad(){
let{results}=awaitapi.fetchImages()
letcol=2
for(leti=0;i<col;i++){
this.data.list[i]=newArray(results.length/2)
}
this.setData({
list:this.data.list
})
for(letiinresults){
results[i].cover=results[i].imageUrl
letinfo=awaitthis.loadImage(results[i].cover)
results[i].height=165/info.width*info.height
if(i<col){
this.data.list[i][0]=results[i]
this.data.heightArr.push(results[i].height)
}else{
letminHeight=Math.min.apply(null,this.data.heightArr)
letminHeightIndex=this.data.heightArr.indexOf(minHeight)
letindex=this.data.list[minHeightIndex].filter(Boolean).length
this.data.list[minHeightIndex][index]=results[i]
this.data.heightArr[minHeightIndex]+=results[i].height
}
}
for(leti=0;i<col;i++){
this.data.list[i]=this.data.list[i].filter(Boolean)
}
this.setData({
list:this.data.list
})
},
loadImage(cover){
returnnewPromise(resolve=>{
wx.getImageInfo({
src:cover,
success:(res)=>{
resolve(res)
}
})
})
}
})

这个例子中就在图片没有加载完之前给了一个默认的加载中的显示,当然这只是一个简单的例子,只能提供简单的优化思路,实际中的加载过渡动画一定会设计得更细腻

云存储获取用户信息

一般小程序中用到的图片都是存储在云服务器上的,且云服务器一般都会提供在图片请求地址上带参数获取图片信息,以阿里云为例,可以在图片链接上拼接?x-oss-process=image/info,就能获取到图片信息,举个例子:

<viewclass="fall">
<viewclass="fall-column"wx:for="{{list}}"wx:for-index="idx"wx:for-item="column"wx:key="{{idx}}">
<viewclass="fall-column-item"wx:for="{{column}}"wx:for-index="i"wx:for-item="item"wx:key="{{i}}">
<imageclass="fall-column-item-img"src="{{item.cover}}"mode="widthFix"/>
</view>
</view>
</view>
.fall{
display:flex;
background-color:#f7f7f7;
}

.fall-column{
display:flex;
flex-direction:column;
margin-left:30rpx;
}

.fall-column-item{
position:relative;
margin-top:30rpx;
line-height:0;
background-color:#ccc;
}

.fall-column-item::after{
content:'加载中';
position:absolute;
top:50%;
left:50%;
transform:translate(-50%,-50%);
display:inline-block;
color:#666;
}

.fall-column-item-img{
position:relative;
width:330rpx;
z-index:1;
}
letfetchPicInfo=async(url)=>{
let[err,result]=awaitto(testFly.get(`${url}?x-oss-process=image/info`))
if(err)throwerr
returnresult.data
}
importapifrom'../../api/index'
Page({
data:{
list:[],
heightArr:[]
},
asynconLoad(){
let{results}=awaitapi.fetchImages()
letcol=2
for(leti=0;i<col;i++){
this.data.list[i]=newArray(results.length/2)
}
this.setData({
list:this.data.list
})
for(letiinresults){
results[i].cover=results[i].imageUrl
letinfo=awaitapi.fetchPicInfo(results[i].cover)
results[i].height=165/info.ImageWidth.value*info.ImageHeight.value
if(i<col){
this.data.list[i][0]=results[i]
this.data.heightArr.push(results[i].height)
}else{
letminHeight=Math.min.apply(null,this.data.heightArr)
letminHeightIndex=this.data.heightArr.indexOf(minHeight)
letindex=this.data.list[minHeightIndex].filter(Boolean).length
this.data.list[minHeightIndex][index]=results[i]
this.data.heightArr[minHeightIndex]+=results[i].height
}
}
for(leti=0;i<col;i++){
this.data.list[i]=this.data.list[i].filter(Boolean)
}
this.setData({
list:this.data.list
})
}
})

通过这个方法可以大大减少图片加载的时间,不需要将图片下载到本地在获取图片信息,而是直接向服务器请求图片信息,再加上每次请求只会返回图片基本信息就几个字段,因此请求时间也非常短,如图:小程序中的瀑布流是什么意思

这样用户能更快看到图片显示,同时也加上了图片加载时的过渡效果,这样体验效果会更好

关于“小程序中的瀑布流是什么意思”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

发布于 2021-03-17 20:51:07
收藏
分享
海报
0 条评论
163
上一篇:微信小程序之如何调用微信授权窗口 下一篇:php正则替换函数preg_replace怎么用
目录

    0 条评论

    本站已关闭游客评论,请登录或者注册后再评论吧~

    忘记密码?

    图形验证码