Skip to main content

瀑布流

绝大部分的商业级都是 js 实现的瀑布流,比如 isotope 等插件

js + absolute 方案

可以考虑把子元素全部设置成绝对定位。然后onResize 监听图片加载,等图片加载完,就把图片挨个设置到高度最低的位置,即逐个塞到父容器中。

js 实现 1.创建图片元素 2.设置每张图片的位置 3.监听窗口改变

const imgWidth = 220; //每张图片的固定宽度

// 1. 加入图片元素
function createImgs() {
for (let i = 0; i <= 40; i++) {
const img = document.createElement("img");
img.src = i + ".jpg";
img.onload = setPosition;

container.appendChild(img);
}
}

// 假设一行有三列,放置图片位置时
// 只要找三列中高度最低的一列,把图片放上去并更新高度(利用绝对定位)
function setPosition() {}

// 触发onResize时,要重新计算列数,并重新把图片放上去

优点

控制灵活,随意扩展。 也可以无限加载,不用过多考虑兼容问题。 同时可以添加诸多动画来增强用户体验。

缺点

实现相对复杂。 图片填充需要考虑图片加载状态。 性能逊色于纯 css 实现。

flex 方案

.img-wrapper {
display: flex;
flex-wrap: wrap;
flex-direction: column;
height: 1300px;
}

.img-wrapper > li {
position: relative;
width: calc(100% / 4);
padding: 5px;
box-sizing: border-box;
}

对父容器设置弹性盒后,因为瀑布流是多行的所以还要 flex-wrap 设置 wrap,并且 flex-direction 还要设置为 column。最关键的是一定要设置一个高度。当然在其子元素用百分比设定要显示几列。 就这样,flex 也可以实现一个瀑布流了。 当然,我们如果想改变一定程度的序列优先级,可以改变 css 的 order 属性。

.img-wrapper > li:nth-child(4n + 1) {
order: 1;
}
.img-wrapper > li:nth-child(4n + 2) {
order: 2;
}
.img-wrapper > li:nth-child(4n + 3) {
order: 3;
}
.img-wrapper > li:nth-child(4n) {
order: 4;
}

优点

实现相对简单。 图片自动填充不用考虑图片加载状态。 顺序在一定程度上可以改变。

缺点

高度是固定的,很难做活。 顺序虽然可以改变,但是仍然不灵活,不尽人意。

引用 https://juejin.cn/post/7014650146000470053