小程序中的瀑布流

阅读 31339  ·  发布日期 2020-08-24 17:26  ·  温州优光网络科技有限公司|建站|APP小程序制作|做网站SEO推广优化
【摘要】 瀑布流是一种很常见的网页布局,视觉表现为参差不齐的多栏布局,是一种时下很流行的布局形式,最近在写小程序恰好也碰到了,想了几种不同的实现方法,接下来就来一起看看具体的实现方法(所用的方法中用的例子都是两栏的布局)。等高的瀑布流等高的瀑布流顾名思义就是瀑布流里的单个盒子的高度都是一样的,这种形式的瀑布流实现起来也比较简单,... 【温州小程序开发,温州微信公众号,平阳做网站,平阳网站建设公司,平阳小程序商城制作,昆阳万全做网站,鳌江水头小程序,萧江腾蛟微信公众号,山门顺溪南雁海西南麂凤卧麻步怀溪网络网店服务,政采云网店管理服务】...

小程序中的瀑布流

瀑布流是一种很常见的网页布局,视觉表现为参差不齐的多栏布局,是一种时下很流行的布局形式,最近在写小程序恰好也碰到了,想了几种不同的实现方法,接下来就来一起看看具体的实现方法(所用的方法中用的例子都是两栏的布局)。
等高的瀑布流等高的瀑布流顾名思义就是瀑布流里的单个盒子的高度都是一样的,这种形式的瀑布流实现起来也比较简单,因为不涉及到盒子高度的计算,举个例子:
Page({
data: {
list: [] }
, onLoad () {
let images = [] for (let i = 0;
i 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布局,允许换行,设置好瀑布流里中每一个盒子的宽高,就能实现简单的实现两栏瀑布流布局不等高瀑布流不等高瀑布流是更为常见的形式,不等高瀑布流涉及到列高的计算,由于每个盒子的高度不一样,因此需要每一列的列高都要记录、比较,将下一个盒子插入高度矮的一列,接下来就来看看不等高瀑布流的实现方式已知盒子高度一般瀑布流里展示的都是图片,这种情况指的是服务端会返给前端要展示的图片的宽高,这种情况下相对也比较简单,因为服务端会返回图片的宽高,前端只需要计算一下列高,将下一张图片插入矮的那里一列就可以,举个例子:
.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) {
let images = [] let scale = 2 // 模拟图片宽高 for (let i = 0;
i i++) {
let image = this.data.images[Math.floor(Math.random() * 10)] images.push(image) }
for (let i in images) {
let height = 165 / images[i].width * images[i].height * scale images[i].showHeight = height // 第一行的两个盒子 if (i this.data.list.push([images[i]]) this.data.heightArr.push(height) }
else {
// 选出高度较矮的一列的索引 let minHeight = Math.min.apply(null, this.data.heightArr) let minHeightIndex = 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可以获取到图片宽高信息,举个例子:
.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;
}
import api from '
../../api/index'
Page({
data: {
list: [], heightArr: [] }
, async onLoad () {
let {
results}
= await api.fetchImages() let col = 2 for (let i in results) {
results[i].cover = results[i].imageUrl // 获取图片信息 let info = await this.loadImage(results[i].cover) results[i].height = 165 / info.width * info.height if (i this.data.list.push([results[i]]) this.data.heightArr.push(results[i].height) }
else {
let minHeight = Math.min.apply(null, this.data.heightArr) let minHeightIndex = 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) {
return new Promise(resolve => {
wx.getImageInfo({
src: cover, success: (res) => {
resolve(res) }
}
) }
) }
}
)当服务端没有返回图片的宽高时,可以直接通过wx.getImageInfo()获取到图片的信息,这里为了不打乱服务返回时的图片顺序,特意将这个单独用Promise封了一层,就是为了图片加载完一张再获取下一张,但是当图片比较大的时候就会导致加载的时间会很长,会有长时间的白屏:
这是因为wx.getImageInfo()获取图片信息的时候会先将图片下载下来,然后才能获取图片信息,这就导致时间会比较长,但是如果不需要图片加载顺序时可以考虑直接并行加载,不等上一张图片加载完就加载下一张,这样就能更快的展现wx.getImageInfo优化既然图片加载获取信息时间比较长,那考虑是否可以加上一个默认的图片,这样用户能在第一时间看到有内容展示,图片信息拿到后再将图片显示出来,举个例子:
.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;
}
import api from '
../../api/index'
Page({
data: {
list: [], heightArr: [] }
, async onLoad () {
let {
results}
= await api.fetchImages() let col = 2 for (let i = 0;
i i++) {
this.data.list[i] = new Array(results.length / 2) }
this.setData({
list: this.data.list }
) for (let i in results) {
results[i].cover = results[i].imageUrl let info = await this.loadImage(results[i].cover) results[i].height = 165 / info.width * info.height if (i this.data.list[i][0] = results[i] this.data.heightArr.push(results[i].height) }
else {
let minHeight = Math.min.apply(null, this.data.heightArr) let minHeightIndex = this.data.heightArr.indexOf(minHeight) let index = this.data.list[minHeightIndex].filter(Boolean).length this.data.list[minHeightIndex][index] = results[i] this.data.heightArr[minHeightIndex] += results[i].height }
}
for (let i = 0;
i i++) {
this.data.list[i] = this.data.list[i].filter(Boolean) }
this.setData({
list: this.data.list }
) }
, loadImage (cover) {
return new Promise(resolve => {
wx.getImageInfo({
src: cover, success: (res) => {
resolve(res) }
}
) }
) }
}
)这个例子中就在图片没有加载完之前给了一个默认的加载中的显示,当然这只是一个简单的例子,只能提供简单的优化思路,实际中的加载过渡动画一定会设计得更细腻云存储获取用户信息一般小程序中用到的图片都是存储在云服务器上的,且云服务器一般都会提供在图片请求地址上带参数获取图片信息,以阿里云为例,可以在图片链接上拼接?x-oss-process=image/info,就能获取到图片信息,举个例子:
.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;
}
let fetchPicInfo = async (url) => {
let [err, result] = await to(testFly.get(`${
url}
?x-oss-process=image/info`)) if (err) throw err return result.data }
import api from '
../../api/index'
Page({
data: {
list: [], heightArr: [] }
, async onLoad () {
let {
results}
= await api.fetchImages() let col = 2 for (let i = 0;
i i++) {
this.data.list[i] = new Array(results.length / 2) }
this.setData({
list: this.data.list }
) for (let i in results) {
results[i].cover = results[i].imageUrl let info = await api.fetchPicInfo(results[i].cover) results[i].height = 165 / info.ImageWidth.value * info.ImageHeight.value if (i this.data.list[i][0] = results[i] this.data.heightArr.push(results[i].height) }
else {
let minHeight = Math.min.apply(null, this.data.heightArr) let minHeightIndex = this.data.heightArr.indexOf(minHeight) let index = this.data.list[minHeightIndex].filter(Boolean).length this.data.list[minHeightIndex][index] = results[i] this.data.heightArr[minHeightIndex] += results[i].height }
}
for (let i = 0;
i i++) {
this.data.list[i] = this.data.list[i].filter(Boolean) }
this.setData({
list: this.data.list }
) }
}
)通过这个方法可以大大减少图片加载的时间,不需要将图片下载到本地在获取图片信息,而是直接向服务器请求图片信息,再加上每次请求只会返回图片基本信息就几个字段,因此请求时间也非常短,如图:
这样用户能更快看到图片显示,同时也加上了图片加载时的过渡效果,这样体验效果会更好总结这篇文章把最近在写小程序时遇到的瀑布流做了一个比较详细的总结,不同的情况下选择不同的加载方案,体验效果最好的当然还是服务端直接返回图片信息,这样能节省很多获取图片信息要花的时间,这样用户体验更优,希望能对各位在写小程序瀑布流能有所帮助。
如果有错误或不严谨的地方,欢迎批评指正,如果喜欢,欢迎点赞推荐教程:
《微信小程序》以上就是小程序中的瀑布流的详细内容,更多请关注php中文网其它相关文章!
微信
分享相关标签:
前端 小程序本文转载于:
segmentfault,如有侵犯,请联系a@php.cn删除
上一篇:
微信小程序wx.request请求数据报错
下一篇:
微信小程序加载失败是什么原因?相关文章相关视频小程序文本溢出时,如何显示为省略号?小程序内容更新提示小红点如何实现?小程序性能优化的几点实践技巧小程序可以导入视频吗?小程序页面跳转路径怎么获取?小程序中的瀑布流第三方平台开发小程序(一)小程序项目介绍预览认识小程序开发工具 [温州做小程序]