程序里瀑布流模式的特点与应用分析

why 333 2024-07-12

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

等高的瀑布流

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

1

2

<view>

  <view></view></view>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

Page({

  data: {

    list: []

  },

  onLoad () {

    let images = []

    for (let i = 0; i <pre class="brush:php;toolbar:false">.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布局,允许换行,设置好瀑布流里中每一个盒子的宽高,就能实现简单的实现两栏瀑布流布局

不等高瀑布流

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

已知盒子高度

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

1

2

3

4

<view>

  <view>

    <view></view>

  </view></view>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

.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;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

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 <p>上例中为了方便也是用色块模拟了图片,在js中模拟了10张图片的宽高,每次从中随机取10张图片,定义了两列,每次计算一下每列的高度,将图片插入矮的那一列,然后将记录用高度数组,将图片的高度累加,实现起来也很简单</p><h3>未知盒子高度</h3><p>未知盒子高度的情况下,我们要怎么做呢?</p><h4>wx.getImageInfo</h4><p>第一种办法就是通过wx.getImageInfo可以获取到图片宽高信息,举个例子:</p><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"><view>

  <view>

    <view>

      <image></image>

    </view>

  </view></view>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

.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;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

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  {

      wx.getImageInfo({

        src: cover,

        success: (res) =&gt; {

          resolve(res)

        }

      })

    })

  }

})

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

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

wx.getImageInfo优化

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

1

2

3

4

5

6

<view>

  <view>

    <view>

      <image></image>

    </view>

  </view></view>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

.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;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

import api from '../../api/index'

Page({

  data: {

    list: [],

    heightArr: []

  },

  async onLoad () {

    let {results} = await api.fetchImages()

    let col = 2

    for (let i = 0; i  {

      wx.getImageInfo({

        src: cover,

        success: (res) =&gt; {

          resolve(res)

        }

      })

    })

  }

})

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

云存储获取用户信息

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

1

2

3

4

5

6

<view>

  <view>

    <view>

      <image></image>

    </view>

  </view></view>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

.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;

}

1

2

3

4

5

let fetchPicInfo = async (url) =&gt; {

  let [err, result] = await to(testFly.get(`${url}?x-oss-process=image/info`))

  if (err) throw err

  return result.data

}

1

2

3

4

5

6

7

8

9

10

import api from '../../api/index'

Page({

  data: {

    list: [],

    heightArr: []

  },

  async onLoad () {

    let {results} = await api.fetchImages()

    let col = 2

    for (let i = 0; i <p>通过这个方法可以大大减少图片加载的时间,不需要将图片-到本地在获取图片信息,而是直接向服务器请求图片信息,再加上每次请求只会返回图片基本信息就几个字段,因此请求时间也非常短,如图:<br><img src="https://img.php-/upload/image/137/787/730/1592535565112393.png" title="1592535565112393.png" alt="75a59de6d3b987f5baae040cbdb4cfb.png"></p><p>这样用户能更快看到图片显示,同时也加上了图片加载时的过渡效果,这样体验效果会更好</p><h2>总结</h2><p>这篇文章把最近在写小程序时遇到的瀑布流做了一个比较详细的总结,不同的情况下选择不同的加载方案,体验效果最好的当然还是服务端直接返回图片信息,这样能节省很多获取图片信息要花的时间,这样用户体验更优,希望能对各位在写小程序瀑布流能有所帮助。<br><br>如果有错误或不严谨的地方,欢迎批评指正,如果喜欢,欢迎点赞</p><p>推荐教程:《<a href="https://www.php-/weixin-marketing.html" target="_blank">微信小程序</a>》</p>

以上就是小程序中的瀑布流的详细内容。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:微信拍了拍功能的含义及作用详细解读
下一篇:微信小程序中 wx.request 请求数据报错的原因及解决策略
相关文章

 发表评论

暂时没有评论,来抢沙发吧~