瀑布流的核心就是每次找出最短的一列后将新图片插入其后面

如果对顺序没有太大要求可以用纯CSS瀑布流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
class FallFlow {

constructor(container, imgList, options) {
this.container = container
this.imgList = imgList
this.options = options
this.createImgs()
}

/**
* 生成图片
*/
createImgs() {
const template = document.createDocumentFragment()
for (let i = 0; i < this.imgList.length; i++) {
const img = document.createElement('img')
img.src = this.imgList[i]
template.appendChild(img)
// container.appendChild(img)
}
this.container.appendChild(template)
this.setImgsPosition()
}

/**
* 计算列数
*/
calculateCol() {
// 容器宽度
const containerWidth = this.container.clientWidth
// 列数量
const columns = Math.floor(containerWidth / this.options.minColWidth)
// 总间隔
const totalGap = (columns + 1) * this.options.gap
// 列宽
const colWidth = (containerWidth - totalGap) / columns

return {
columns, totalGap, colWidth
}
}

/**
* 设置图片位置
*/
setImgsPosition() {
const { columns, colWidth } = this.calculateCol()
// 每列高度
let nextTops = new Array(columns).fill(this.options.gap)

for (let i = 0; i < this.container.children.length; i++) {

const img = this.container.children[i]

img.width = colWidth

// 最小的高度
const minTop = Math.min(...nextTops)

// 需更新高度的坐标
const minIndex = nextTops.indexOf(minTop)

// 更新高度
nextTops[minIndex] += img.height + this.options.gap

// 横向偏移
const left = minIndex * colWidth + (minIndex + 1) * this.options.gap + 'px'

// 设置图片偏移量
img.style.transform = `translateY(${minTop}px) translateX(${left})`
// img.style.top = minTop + 'px'
// 设置图片的left偏移量
// img.style.left = minIndex * colWidth + (minIndex + 1) * this.options.gap + 'px'
}

const max = Math.max(...nextTops)
container.style.height = max + 'px'
}
}

const imgList = [
// ...省略
]

const container = document.querySelector('.container')

const fallFlow = new FallFlow(container, imgList, {
minColWidth: 300,
gap: 10
})

let timer = null
window.addEventListener("resize", () => {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(()=> {fallFlow.setImgsPosition()}, 300)
})