小程序实现无限瀑布流

释放双眼,带上耳机,听听看~!

实现瀑布流

实现效果

小程序实现无限瀑布流

有好几种方案

1.用column-count属性把页面元素分为俩列或多列来实现

2.用display flex 分列来展示页面

3.比如说用js实现

我今天介绍的就是第三种,因为前两种都会有局限,实现的效果我们希望是左右左右,而不是分成两列去显示,因为如果功能需要列表按照热度显示,从我们视觉来看就是 左右比较好,而不是一整列 1,2,3,4,5…

当然如果你们希望用column-count 实现的话,也可以 请点击,我随便找了一个网址网上有很多,我自己也试过实现起来确实很简单,纯css3实现。

那么好,现在正式开始:

说一下思路,通过js控制两列数组,分别在这两个数组中插入图片实现列表展示

首先HTML布局

<view class=\"post-content\" wx:if=\"{{list.length}}\">
  <view class=\"left-view\">
    <repeat for=\"{{leftList}}\" key=\"index\" index=\"index\" item=\"item\">
      <PostItem :item.sync=\"item\" imgMode=\"widthFix\" />
    </repeat>
    </view>
    <view class=\"right-view\">
    <repeat for=\"{{rightList}}\" key=\"index\" index=\"index\" item=\"item\">
      <PostItem :item.sync=\"item\" imgMode=\"widthFix\" />
    </repeat>
  </view>
</view>

可以看到就是一个外部大壳子,然后两列 left-view、right-view 之后就是两个数组循环展示,PostItem是我自己封装的组件用来展示单个item

css部分

.post-content {
  padding: 0 24rpx;
  padding-top: 24rpx;
  box-sizing: border-box;
  > view {
    width: 49%;
    display: inline-block;
    vertical-align: top;
  }

  .left-view {
    margin-right: 2%;
  }
}

也很简单两列宽度约等于50%中间有间隔

js部分

loadImages () {
  setTimeout(() => {
    const data = this.list
    let { leftList, rightList } = this
    if (data.length) {
      for (let i = 0; i < data.length; i++) {
        if (data[i].id % 2 == 1) {
          leftList.push(data[i])
        } else {
          rightList.push(data[i])
        }
      }

      this.leftList = leftList
      this.rightList = rightList
      this.$apply()
    }
  }, 1000);
}

data = {
  leftList: [], //左列
  rightList: [], //右列
}

就可以看到下列图

但是如果只是这样实现的话就会有问题,因为它的实现是按照奇偶数实现的,那么如果有几张图片正好很高,那么另外一列就会很难看。

小程序实现无限瀑布流

下列有问题的情况

小程序实现无限瀑布流

可以看到左列很难看

那么我做一下修改, 在遍历数据的时候做了左右列表的高度检测,如果那边底那么就append到哪边

loadImages (list) {
  const newList = list || this.list
  setTimeout(() => {
    let { leftList, rightList } = this
    if (newList.length) {
      helper.forSetTimeout(newList,async (i) => {
        const isLeft = await this.isPushLeft()
        if (isLeft) {
          leftList.push(newList[i])
        } else {
          rightList.push(newList[i])
        }

        this.leftList = leftList
        this.rightList = rightList
        this.$apply()
      }, 50)
    }
  }, 300);
}


// forSetTimeout 实现
function forSetTimeout (list, callback, time = 1000) {
    for (let i = 0; i < list.length; i++) {
        setTimeout(((num) => {
            return callback.bind(null, num)
        })(i), i * time)
    }
}

isPushLeft () {
  const query = wepy.createSelectorQuery()
  query.select(\'.left-view\').boundingClientRect()
  query.select(\'.right-view\').boundingClientRect()
  return new Promise((resolve, reject) => {
    query.exec((res) => {
      const leftData = res[0]
      const rightData = res[1]
      resolve(leftData.height < rightData.height)
    })
  })
}

最终效果如最上面的图,事实上setTimeout的时间间隔可以改成30毫秒以内,但是我觉得50毫秒已经不影响正常体验了。

给TA打赏
共{{data.count}}人
人已打赏
随笔日记

排序算法——(1)简介

2020-11-9 3:50:46

随笔日记

华凯创意上市第二年净利降62% 董监高减持套现过亿

2020-11-9 3:50:48

2 条回复 A文章作者 M管理员
  1. 有源码吗

    • 您可以联系作者咨询,现在有专门对接小程序的软件

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索