瀑布流布局(multi-column多列布局)

 效果展示:

 

瀑布流布局是网页设计常见的一种布局,一般用于图片多列展示。列宽固定,图片根据自身高度自适应交错排列。 

 特点:

  • 等宽不等高,多列布局;
  • 随着页面滚动条向下滚动,不断加载数据块并附加至当前尾部;
  • 每行排满后,新的图片添加到后面
  • 窗口尺寸改变,重新计算布局

优点

  • 节省空间:降低页面的复杂
  • 对于 触屏设备非常友好:通过向上滑动浏览,交互方式更符合直觉
  • 良好的视觉体验:浏览时不会被页面整整齐齐的高度影响,参差不齐,降低浏览的疲劳

缺点

  • 内容总长度 无法掌握
  • 数据过多时,容易造成页面 加载的负荷
  • 再次加载时 很难定位上一次浏览的内容

理想效果:

  • 列宽固定,图片根据自身高度自适应交错排列;
  • 排列规则:第一行图片按顺序排满一行,后面的图片按照规则放在高度最小的列下面;
  • 图片触底更新,按需加载;
  • 窗口大小改变,自适应图片的列数;
  • 最底部对齐;

实现方法

一、纯CSS实现(multi-column 多列布局)

用到属性

column-count : 定义列数
column-gap :列与列之间的间隔

特点

顺序只能是 从上到下 再左到右

缺点

由于排列顺序是先 从上到下 再左到右,只能用于数据固定, 无法动态的加载追加,对于滚动到底部加载新数据则无法实现。

4.注意点:

有时候页面会出现在前几列的最后一个元素的内容被自动断开,一部分在当前列尾,一部分在下一列的列头。这时候子元素可以用 break-inside设置为不被截断 avoid来控制,像下面这样

break-inside: avoid; // 不被截断 默认值是auto,会被截断

5、实现思路:

  •  外层盒子定义列数和列间距
  • 每项 item 设置 break-inside: avoid; 让它不被截断

 二、flex布局实现

实现思路:

  • 将最外层元素设置为 display: flex,即横向排列。
  • 设置 flex-flow:column wrap 使其换行。
  • 设置 height: 100vh 填充屏幕的高度,来容纳子元素。
  • 每一列的宽度可用 calc 函数来设置,即 width: calc(100%/3 - 20px)。分成等宽的 3 列减掉左右两边的 margin 距离。

缺点:

不能动态添加数据

三、JS绝对定位实现(不推荐使用)

原理:

精确计算每个子元素绝对定位到瀑布流它应该去的地方,需要后期一些优化,并不推荐使用

缺点:

  • 计算量大,较复杂
  • 会有高度塌陷问题
  • 子元素因为设置了 absolute并不会占高,页面可滚动的话又会产生另外的问题
  • 如果在移动端中会做适配,当前的绝对定位的高度单位在代码实现若为px 并不会自动换算
  • 当视口的窗口resize改变,需要重新计算元素的位置,若会不断触发事件,性能消耗大,加载也慢,这是不可取的

关键数据:

  • 列的数量
  • 图片宽度固定
  • 间隙
  • 容器宽度

实现思路:

1、创建图片容器、元素

2、绝对定位设置每张图片的位置

  • 子元素全部设置成绝对定位
  • 找到所有列中>最小的位置
  • 计算子元素定位时的 top 以及left
  • 修改子元素的样式,设置position为absolute ,以及设置top ,left
  • 每次插入的位置选择所有列高度最小 的位置,依次循环

3、监听窗口改变,重新设置图片位置

定义数据和ui样式

数据设计

imgsArr_c 是 增加height属性后的新图片数组

 

 

图片预处理

列宽 = 整个容器的宽度 / 列数

图片宽度 = 列宽 - (间隔 * 2)

实现图片按原始比例缩放:图片高度 = 图片宽度 * (原始图片高度 / 原始图片宽度)

若加载失败则设置图片高度与宽度一致,加载成功则按原始比例动态计算图片高度

加载图片

懒加载,预加载,压缩图片

这里需要注意的是,vue 中数据的变化到 DOM 的重新渲染是一个异步过程。vue 中当 data 改变后,并不是立即渲染到页面上的,而是先放到事件队列上。然后,在下一个的事件循环中,Vue 刷新事件队列并执行实际 (已去重的) 工作。这就导致了,数据改变后挂载在 dom 上可能会存在一定的延迟,所以数据改变后立刻去获取 dom 元素可能拿到的不是最新的值而是改变前的值。

所以,使用 $nextTick 来对解决这个问题,$nextTick 的作用就是在下次 dom 更新循环结束后执行其 callback。在修改 imgsArr_c 之后使用这个方法,才能保证排列的元素是更新后的。

 设置图片行内样式宽高

设置瀑布流

设置图片的高度,top,left

第一行:
  • top = 0
  • left = 索引 * 列宽
第二行往后的 n 行:
  • 拿到当前高度最低的列高 minHeight,返回其索引 minIndex
  • Math.min.apply(null,  arr),表示获取数组中最小的值
  • top = 最小列的高度值
  • left = 最小列的索引 * 列宽
  • 更新最小列高度 = 原来的高度 + 新加的图片高度

 

 增加图片间隔在 top 和 列高 都要加

 调用预加载图片函数

拿到视口大小

 到此,JS实现瀑布流实现完成。

以下是优化部分:

触底更新图片

图片懒加载

在Vue中JS定位实现瀑布流

注意点:axios获取数据,不可在其他方法中拿到,但模板可以使用

四、CSS瓦片布局实现

基于Grid 布局实现的,除了火狐浏览器其他都不支持,兼容性差,Pass掉了。

Vue中瀑布流布局与图片加载优化的实现_vue.js_脚本之家

用 vue 实现瀑布流_vue 瀑布流_hhhqzh的博客-CSDN博客

实现瀑布流布局的四种方法_Smile_zxx的博客-CSDN博客

猜你喜欢

转载自blog.csdn.net/iaz999/article/details/131715268
今日推荐