三行代码实现完美瀑布流

需求

最近准备做一个瀑布流的需求,这里每个卡片的高度是不固定的,有点类似下图这样的。

难点

  1. 如果绝对定位,如何定位每个卡片的位置。 因为可以发现需求里边的每个卡片的高度都是不固定的,所以如果想使用绝对定位的话,需要实时动态的计算每个卡片的left、top,这里会涉及大量的计算。

因为每个卡片的高度是不固定,所以如果想要计算left、top,必须首先获取卡片的高度,但是卡片里边不仅包含图片,还有文字,这个时候计算高度是比较困难的。

  1. 如何结合虚拟列表实现瀑布流

这个时候必须要根据scrollTop的位置,判断什么时候需要加载哪些数据,判断可视区域里边数据的起始索引以及结束索引,这里同样会涉及大量的计算,同时还因为每个卡片的高度不固定,甚至只有图片和文字加载到浏览器以后,才能得到真实的高度,这样会更困难。

解决方案

解决方案1

  1. 如果绝对定位,如何定位每个卡片的位置。

1.1 后端计算 后端可以先把每个图片的高度和宽度提前计算好,直接返回给前端进行处理,然后前端根据后端返回的图片高度和宽度,然后再动态的计算出每个卡片的高度(文字部分也可以固定高度,使用省略号实现)。

1.2 前端计算

前端计算还是比较麻烦的,需要先等卡片组件加载完成,才能得到宽度和高度,而且因为数据量比较大,每个卡片计算出来以后,还需要去根据计算出来的结果去更新left、top,会非常麻烦。 这里可以采用node作为中间层进行计算,还是使用类似后端计算的思路。

还有一种方法是使用observe api 动态观察每个卡片,当观察到卡片加载完成后,再动态根据卡片的宽度和高度计算,不过这样同样很麻烦。

  1. 如何结合虚拟列表实现瀑布流

这里因为卡片的高度是不固定的,同时也是瀑布流,所以不能使用react-window 来解决,不过可以使用react-window的类似思路,自己封装一个npm 包,根据scroll事件判断需要加载那些数据。

解决方案2

使用css3的columns来实现,该技术解决方案不需要计算高度,也不需要去定位,但是columns这个属性会把卡片高度给切开 如下图:

不过可以使用下面代码来解决,

js 复制代码
.test {
  // color: red;
  // height: 2000px;
  background-color: red;
  gap: 1rem;
  columns: 5;
  .no-break {
    break-inside: avoid;
  }
}

效果如下:

相关推荐
swipe20 小时前
纯函数、柯里化与函数组合:从原理到源码,构建更可维护的前端代码体系
前端·javascript·面试
远山枫谷20 小时前
uniapp + Vue 自定义组件封装:自定义样式从入门到实战
前端·vue.js
Lee川20 小时前
JavaScript 中的 `this` 与变量查找:一场关于“身份”与“作用域”的深度博弈
前端·javascript·面试
Kakarotto1 天前
Canvas 直线点击事件处理优化
javascript·vue.js·canvas
顺遂1 天前
基于Rokid CXR-M SDK的引导式作业辅导系统设计与实现
前端
代码搬运媛1 天前
Generator 迭代器协议 & co 库底层原理+实战
前端
前端拿破轮1 天前
从0到1搭建个人网站(三):用 Cloudflare R2 + PicGo 搭建高速图床
前端·后端·面试
功能啥都不会1 天前
PM2 使用指南 - 踩坑记录
前端
HelloReader1 天前
React 中 useState、useEffect、useRef 的区别与使用场景详解,终于有人讲明白了
前端
兆子龙1 天前
CSS 里的「if」:@media、@supports 与即将到来的 @when/@else
前端