lin-ui icon indicating copy to clipboard operation
lin-ui copied to clipboard

瀑布流组件图片mode为widthFix时,瀑布流两边会一边长一边短

Open xyfll7 opened this issue 4 years ago • 7 comments

瀑布流组件图片mode为widthFix时,瀑布流两边会一边长一边短

这是因为图片还没加载出来瀑布流已经提前去获取图片尚未加载结束时的 card高度,图片加载结束以后又会再次改变card的高度,导致某一列延长,而另外一列缩短。 粗暴的解决方式可以将传进去的数组简单拆分,分批上屏即可。。

  这样调用renderWaterFlow就会正常显示。
  if(!this.graphics) return
      const t = JSON.deep([...this.graphics])
      for(;;) {
        const a = t.splice(0,2) // 这里只能是2,其余的数字都不太正常。
        if(!a.length) break;
        wx.lin.renderWaterFlow(a, false ,()=>{
          console.log('渲染成功')
        })
      }

image

xyfll7 avatar Jul 09 '20 04:07 xyfll7

您好,可以提供一下相关的代码以及你所用的图片链接吗,我这边简单测了一下暂时没有发现这个问题

juzi214032 avatar Jul 10 '20 01:07 juzi214032

只需要将虚拟节点中的 image标签设置属性为: mode="widthFix" lazy-load 采用不同宽高比的图片加载进去就会一边长一边短。

你们的示例代码,所有图片高度都是相等的,所以water-flow组件中 boundingClientRect 函数能够及时拿到card的高度,

如果image 属性 mode="widthFix" ,在图片加载完成完成之后,图片的高度会自行调整一次,在调整之前,boundingClientRect已经获取了所有card的高度,调整之后card高度又变了一次。。才导致这个问题。

   可以将water-flow的源码这样改造一下,card两个两个上屏,就会正常。原api不变。
    _init() {
      wx.lin = wx.lin || {}, wx.lin.renderWaterFlow = (t = [], e = !1, a) => {
        const x = JSON.deep(t)     //  JSON.deep = obj => JSON.parse(JSON.stringify(obj))
        for (; ;) {
          const b = x.splice(0, 2)
          if (!b.length) break;
          this._renderWaterFlow(b, e)
        }
        a && a()
      }
    },
    _renderWaterFlow(t = [], e = !1) {
      if ("[object Array]" !== Object.prototype.toString.call(t)) return console.error("[data]参数类型错误,渲染失败"), !1;
      this.setData({ data: t }),
        e && (this.data.leftData = [], this.data.rightData = []), this._select(t, e).then(() => { }).catch(t => {
          console.error(t)
        })
    },

xyfll7 avatar Jul 10 '20 02:07 xyfll7

您好,这个问题我已经复现了。感谢您提供的解决思路,但您的这种解决方案好像只是相当于做了一个延时操作,让boundingClientRect在图片加载完后才获取高度,是这样吗

juzi214032 avatar Jul 12 '20 08:07 juzi214032

您好这个问题我已经复现了。感谢您提供的解决思路但您的这种解决方案好像只是相当于做了一个延时操作,让boundingClientRect在图片加载完后才获取高度是这样吗

我的本意是使用setTimeout回调方式等待前2张图片完全被渲染完成,再延时调用boundingClientRect再渲染2张,但是实践结果发现,并不需要setTimeout直接for boundingClientRect即可。 说明只要给图片传入src,无论是否已经显示图片boundingClientRect都可以拿到正确的card高度值?人家内部怎么封装的咱也不知道啊。

补充,好像还是需要setTimeout做延迟,之前不需要是因为我的那几张图片高度刚好吻合。后来换了图片,长度又不一样了。

    _init() {
      wx.lin = wx.lin || {}, wx.lin.renderWaterFlow = (t = [], e = !1, a) => {
        const x = JSON.deep(t)
        // for (; ;) {
        //   const b = x.splice(0, 2)
        //    if (!b.length) break;
        //   this._renderWaterFlow(b, e)
        // }
        const zzz = (wait) => {
          const b = x.splice(0, 2)
          setTimeout(() => {
            console.log(b.length)
            if (b.length) {
              this._renderWaterFlow(b, e)
              zzz(500)
            };
          },wait)
        }
        zzz(0)
        a && a()
      }
    },

xyfll7 avatar Jul 13 '20 03:07 xyfll7

还有一个问题,这明显是一个无限长列表,card数量一旦多起来,会有明显的性能问题。 可以给每个card内部放一个 this.createIntersectionObserver().relativeToViewport({}).observe(#card${_id}, (res) => {}) 当这个card离开交叉口范围就自动隐藏(同时必须保留card自身高度,否则会出现塌陷)。这样就可以解决性能问题了。

但是这个代码似乎需要用户自己添加到虚拟节点内部,如果能封装进 虚拟节点的父组件,多用户隐藏,就再好不过了。

xyfll7 avatar Jul 13 '20 03:07 xyfll7

我也遇到这种情况.

objcxiaobai avatar Jul 16 '20 03:07 objcxiaobai

请问1.0版本会修复此问题吗

ElanYoung avatar Dec 24 '20 07:12 ElanYoung