实现瀑布流思路:父盒子相对定位,子元素绝对定位
<template>
<div class="pbl_box">
<div
v-for="ele of domList"
:key="ele.id"
class="img_box"
:style="{
width: ele.width,
height: ele.height + 'px',
left: ele.left + 'px',
top: ele.top + 'px',
}"
>
<div>{{ ele.id }}</div>
<div>top: {{ ele.top }}</div>
<div>left: {{ ele.left }}</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, nextTick } from 'vue'
let LINE_ROW_NUM = 8; // 每行个数
let IMG_WIDTH = 200;
const domList = ref<IDomInfo[]>([]);
nextTick(() => {
LINE_ROW_NUM = Math.floor(getScreenWidth() / IMG_WIDTH);
if(!LINE_ROW_NUM) {
return false;
}
domList.value = setPosition(createDomList(), IMG_WIDTH);
})
function getScreenWidth() {
let width = getStyle('.pbl_box', 'width')
return Number(width)
}
function setPosition(arr: IDomInfo[], width: number) {
arr.forEach((ele, index) => {
let i:number = index % LINE_ROW_NUM; // 下标
ele.left = width * i; // 左侧定位始终为图片宽度乘下标
if(index < LINE_ROW_NUM) { // 第一排
ele.top = 0;
} else {
let row: number = Math.ceil((index + 1) / LINE_ROW_NUM); // 行数
let last: number = (index - LINE_ROW_NUM) % LINE_ROW_NUM; // 上一行下标
let ci = (row - 1)*LINE_ROW_NUM + last - LINE_ROW_NUM;
// 上排图片顶部定位高度加上高度则为当前行的定位位置
ele.top = arr[ci].top + arr[ci].height
}
})
return arr;
}
function randomRang(start: number, end: number): number {
let total = end - start + 1;
return Math.floor(Math.random() * total + start);
}
// 模拟随机图片高度
function createDomList(): IDomInfo[] {
let arr: IDomInfo[] = [];
while (arr.length < 40) {
let obj: IDomInfo = {
id: arr.length,
width: IMG_WIDTH + 'px',
height: randomRang(150, 200),
top: 0,
left: 0
}
arr.push(obj)
}
return arr;
}
function getStyle(selector: string, key: string) {
const dom: HTMLElement = document.querySelector(selector) as HTMLElement;
if(!dom) {
return 0
}
if(window.getComputedStyle) {
return getComputedStyle(dom, null)[key];
} else {
return dom.currentStyle[key];
}
}
interface IDomInfo {
id: number;
width: string;
height: number;
top: number;
left: number;
}
</script>
<style lang="less" scoped>
.pbl_box {
position: relative;
width: 1900px;
height: 100vh;
overflow-y: auto;
.img_box {
border: 1px solid pink;
position: absolute;
}
}
</style>
瀑布流实现效果图(忽略样式)