收藏
回答

瀑布流问题,好奇image组件在onload的时候是不是做了什么?

因为第一次页面加载的时候显示不正常,之后切换页面就显示的跟预期一样

wxml

  <!-- js高度计算瀑布流  -->
  <view class="left" id="left-box">
    <view wx:for="{{leftList}}" class="item" wx:key="text">
      <image class="item-nail" src="{{item.nail}}" mode="widthFix"></image>
      <view class="item-text">推文{{item.text}}</view>
    </view>
  </view>
  <view class="right" id="right-box">
    <view wx:for="{{rightList}}" class="item" wx:key="text">
      <image class="item-nail" src="{{item.nail}}" mode="widthFix"></image>
      <view class="item-text">推文{{item.text}}</view>
    </view>
  </view>
</view>

js

waterfall(arr, index = 0) {
    if (arr.length <= index) {
      return
    }
    const query = wx.createSelectorQuery().in(this)
    query.select('#left-box').boundingClientRect()
    query.select('#right-box').boundingClientRect()
    query.exec(rects => {
      console.log('eee', rects)
      if ( rects[0].height <= rects[1].height ) {
        this.setData({
          leftList: this.data.leftList.concat([arr[index]])
        })
      } else {
        this.setData({
          rightList: this.data.rightList.concat([arr[index]])
        })
      }
      wx.nextTick(() => {
        this.waterfall(arr, ++index) 
      })
    })
  },

第一次 1,2 ,4,3..

之后1,2,3,4...正常了


为什么呀?,怎么规避第一次即第一次onload 进入出现的问题呢?

回答关注问题邀请回答
收藏

2 个回答

  • 涂之包
    涂之包
    2021-05-14
    mode="widthFix"
    

    你用了这个属性,检查元素可以看见会给 image 加上含内样式 height ,而这个 height 毫无疑问是在图片加载下来之后才能通过 width 计算获取的。而你的瀑布流计算到底放入左还是右时,图片并不一定已经加载完成(但第二次执行时大概率是已经加载完成了的,可以根据 network 查看图片加载时间和你的代码执行时间对比来判断到底是不是这个问题)。除了以上nextTick(延时)执行的方案,更应该在image loaded 加载完成后来执行,但这又引出在多少图片loaded之后执行才合理的问题。以及其他未考虑到的优化问题。具体可以找轮子参考一下。

    2021-05-14
    有用 1
    回复 7
    • 涂之包
      涂之包
      2021-05-14
      另外,看你的代码,waterfall应该是在循环内执行的吧?如果是的话query.exec和setData执行次数就特别多,那这个瀑布流数据稍大些在初始化时就很卡了。
      2021-05-14
      回复
    • 十二篇
      十二篇
      2021-05-17
      是的,原因应该是这个了
      2021-05-17
      回复
    • 十二篇
      十二篇
      2021-05-17
      有的轮子也是这么写的,本质 都是计算高度,避免不了重复setdata,还有什么好的解决方案吗
      2021-05-17
      回复
    • 涂之包
      涂之包
      2021-05-18回复十二篇
      根据屏幕高度和图片高度去计算当前需要setData的图片数组,记录下当前渲染的多少,但这和分页的效果就差不多了。
      另外,有监听图片加载完成的API,可以加载了一定数量的图片后再query和setData。否则就现在来说循环内query的消耗是有些大的。(虽然我也不清楚query消耗多少)
      2021-05-18
      回复
    • 涂之包
      涂之包
      2021-05-18回复涂之包
      想了一下,如果加载一定数量图片,并且已经拿到了图片高度了,那就基本不需要query了,只需要记录left和right的高度。
      2021-05-18
      回复
    查看更多(2)
  • 郑钱花
    郑钱花
    2021-05-14

    推荐你用纯css瀑布流布局https://jessieji.com/2019/pure-css-masonry

    2021-05-14
    有用
    回复
登录 后发表内容