开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第6天,点击查看活动详情
前言
掘友们,大家好啊,这篇文章小编主要给大家讲述一下瀑布流的实现流程,后续会更新瀑布流+懒加载,实现图库式网页的展示效果。
什么是瀑布流
在代码实现之前,我们需要了解下什么是瀑布流。瀑布流是当今网站比较流行的一种网页布局,其布局展示有特性,参差不齐,可以根据页面的滚动,加载相应的信息。这种布局常适用于图片信息网站,用于图片的加载展示,有很好的展示效果,瀑布流特点就是定宽不定高。
代码实现
这里小编是在vue项目中实现的,道理都很简单,下边是源码。
vue
<template>
<div id="pubuliu">
<div v-for="(item, index) in imageList" :key="index">
<img :class="['item', `item${index}`]" :src="item" alt="" />
</div>
</div>
</template>
js
imageList中的数据是图片数据,大家可以更换新的测试一下。
获取父元素的总宽度,再根据元素的宽度,分布式排列,每一行只能设置排列几个元素,添加到数组中,通过数组循环,获取当前元素的高度,让随后元素通过绝对定位,排列到该元素末尾,依次执行。
export default {
name: "login",
components: {},
data() {
return {
imageList: [
"https://img1.baidu.com/it/u=2223176155,1442240853&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1669827600&t=d1a5ae0244318108715612ae0fa76ab5",
"https://img2.baidu.com/it/u=2898829455,2734408317&fm=253&fmt=auto&app=120&f=JPEG?w=1280&h=800",
"https://img1.baidu.com/it/u=2647973744,3827496954&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1669827600&t=d6bdfbb2184baf871271ef9cec6d35e9",
"https://img0.baidu.com/it/u=1036819683,3609732603&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1669827600&t=49d0853367d8c6b9c1b47ad8c06949c1",
"https://img0.baidu.com/it/u=3806884198,2790177765&fm=253&app=138&size=w931&n=0&f=JPG&fmt=auto?sec=1669827600&t=ed8d35f93e7c2797d77924f20a36caae",
"https://img0.baidu.com/it/u=1317822440,3255572922&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1669827600&t=95befb9a8743210989302e6b684a034c",
"https://img0.baidu.com/it/u=3594725999,1437276298&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=281",
"https://img1.baidu.com/it/u=936165722,1965201282&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1669827600&t=46e6a3ee8e54ff4b4fc6e4f993c9a037",
"https://img2.baidu.com/it/u=1565119354,3393975436&fm=253&app=120&size=w931&n=0&f=JPEG&fmt=auto?sec=1669827600&t=8f6165a9eb6f25c1b53cb8d5d81761f7",
"https://img2.baidu.com/it/u=3374881627,2656788225&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1669827600&t=004a961123299c0466153d32fa55deba",
"https://img1.baidu.com/it/u=1101454660,2268298569&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1669827600&t=41aae4f041b0f902b919993349c14ee9",
"https://img2.baidu.com/it/u=3124488439,1080308879&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=1082",
"https://img2.baidu.com/it/u=1661065193,1426179229&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1669827600&t=65967dd2a1804d94de2477eab0ddbb7d",
"https://img1.baidu.com/it/u=219752959,2207818343&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=725",
"https://img1.baidu.com/it/u=2629687430,3233648827&fm=253&fmt=auto&app=138&f=JPEG?w=313&h=500",
"https://img1.baidu.com/it/u=574769240,3416094749&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=281",
"https://img2.baidu.com/it/u=497086471,3307466230&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=281",
],
};
},
methods: {
getHeight() {
// 获取页面宽度
let pageWidth =
document.getElementById("pubuliu").clientWidth;
// 获取图片固定的宽度
let itemWidth = document.getElementsByClassName("item")[0].offsetWidth;
// 设置图片之间间距
let gap = 10;
// 获取一行最多可以展示几张图片
let nums = Math.floor(pageWidth / (itemWidth + gap));
// 瀑布流实现原则:
// 所有图片元素绝对定位,从第二行开始,依次从第一行图片元素高度最小的下方填充,这里注意,不是从左至右填充,即优先填补空位,填补一个后,再填补下一个较大的空位
// 定义第一行图片的所有高度的数组,之后每张图片下方填充图片后,会更新数组对应位置下的最小高度
let heightList = [];
let itemArr = document.getElementsByClassName("item");
let imgLen = itemArr.length;
for (let i = 0; i < imgLen; i++) {
// 如果 当前图片元素索引小于一行最多可以展示的图片个数,说明是第一行,top 已在css中默认设置为0,需要统一设置 left 值,top值如果加gap,则还需设置gap值
if (i < nums) {
// 将第一行的图片元素的高度放入 heightList 数组
heightList.push(itemArr[i].offsetHeight + gap);
itemArr[i].style.top = gap + "px";
itemArr[i].style.left = (itemWidth + gap) * i + "px";
} else {
// 否则从第二行开始,要根据第一行图片元素的高度,设置top和left
// 先假设 heightList[0] 为最小高度
let minItem = {
minHeight: heightList[0],
minIndex: 0,
};
for (let j = 0; j < heightList.length; j++) {
if (heightList[j] < minItem["minHeight"]) {
minItem["minHeight"] = heightList[j];
minItem["minIndex"] = j;
}
}
itemArr[i].style.top = minItem["minHeight"] + gap + "px";
itemArr[i].style.left =
(itemWidth + gap) * minItem["minIndex"] + "px";
// 关键步骤,更新 heightList 中对应位置下整列图片的高度,以便在下次循环时根据heightList 重新寻找最小高度
heightList[minItem["minIndex"]] =
parseFloat(itemArr[i].style.top) +
parseFloat(itemArr[i].offsetHeight);
}
}
}
},
mounted() {
let _this = this;
window.onload = function () {
_this.getHeight()
};
}
};
css
* {
margin: 0;
padding: 0;
}
body {
width: 100vw;
height: 100vh;
}
#pubuliu {
width: 100%;
height: 100%;
overflow: scroll;
position: relative;
background-color: lightgray;
.item {
width: 200px;
height: auto;
box-sizing: border-box;
background: #fff;
border: 1px solid #000;
border-radius: 15px;
text-align: center;
font-size: 40px;
font-weight: bold;
position: absolute;
top: 0;
left: 0;
}
}
结尾
大家完全可以创建vue项目,复制源码,操作一下,实现瀑布流很简单,后续会继续更新瀑布流的懒加载实现原理,希望这篇文章对大家有所帮助。