642 字
3 分钟
瀑布流布局
瀑布流布局
TIP比较流行的一种布局方案,视觉表现为参差不齐的多栏布局,随着页面滚动条滚动,会不断添加数据块并附加到尾部,瀑布流的主要特性便是错落有致,定宽而不定高的设计让页面区别于传统的矩阵式图片布局模式。
Demo: JS动态添加
:::tip 思路
记录每一列的高度,子绝父相定位,利用top和left控制位置,每次增加新成员时,找到高度最小的那一列,并将新成员至于其下方,最后更新每一列的高度。
同时也可利用flex弹性布局或Css3新增的column-*多列布局来实现,不过仅限于一次性加载展示,不需要动态添加的场景。
:::
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>瀑布流布局</title> <style> #container { position: relative; } .item { position: absolute; display: flex; justify-content: center; align-items: center; color: #fff; } </style></head><body> <div id="container"></div>
<script> const column = 3; let counter = 0; const columnHeight = Array(column).fill(0); const container = document.getElementById('container'); const colorList = ["#EAA78C", "#F9CD82", "#9ADEAD", "#9CB6E9", "#E49D9B", "#97D7D7", "#ABA0CA", "#9F8BEC", "#ACA4D5", "#6495ED", "#7BCDA5", "#76B4EF", "#E1C38F", "#F6C46A", "#B19ED1", "#F09B98", "#87CECB", "#D1A495", "#89D196", "#FE9E9F", "#93BAFF", "#D999F9", "#81C784", "#FFCA62", "#FFA477"];
// 生成随机数 function random(min = 0, max = 1) { return min + ~~((max - min) * Math.random()); } // 查找高度最小的列 function findMinColumn(arr) { let min = arr[0]; let index = 0; arr.forEach((v, i) => { if (v < min) { min = v; index = i; } }); return [index, min]; } function appendImg() { const gap = 3; // 间隔 for (let i = 0; i < 12; ++i) { // 每次加载12个元素 const unit = { height: random(100, 500), // 随机一个高度 width: 300, // 定宽 color: colorList[random(0, colorList.length - 1)] // 随机颜色 } const [minIndex, min] = findMinColumn(columnHeight); // 获取高度最小列及下标 const d = document.createElement('div'); d.className = 'item'; d.style.background = unit.color; d.style.height = `${unit.height}px`; d.style.width = `${unit.width}px`; d.style.top = `${min + gap}px`; // 上偏移 d.style.left = `${(300 + gap) * minIndex}px`; // 设置左偏移 d.innerText = `${++counter}#${unit.width}x${unit.height}`; // 设置文字 columnHeight[minIndex] += (unit.height + gap); // 添加后更新列的长度 container.appendChild(d); // 添加节点 } } // 初始化 function init() { appendImg(); // 初始加载 // 是否有某列高度大于屏幕高度 let endLoad = columnHeight.some(v => v > window.innerHeight); if (!endLoad) init(); // 如果没有,就递归调用继续加载 } (function () { init(); // 打开页面自动加载 })()
// 处理浏览器触底事件 window.onscroll = function () { let marginBottom = 0; if (document.documentElement.scrollTop) { let scrollHeight = document.documentElement.scrollHeight; let scrollTop = document.documentElement.scrollTop + document.body.scrollTop; let clientHeight = document.documentElement.clientHeight; marginBottom = scrollHeight - scrollTop - clientHeight; } else { let scrollHeight = document.body.scrollHeight; let scrollTop = document.body.scrollTop; let clientHeight = document.body.clientHeight; marginBottom = scrollHeight - scrollTop - clientHeight; } if (marginBottom <= 0) appendImg(); } </script></body></html>