<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>waterfall</title>
<style>
* {
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
overflow: auto;
}
#container {
width: 100%;
height: 100%;
overflow: auto;
background-color: gray;
display: flex;
justify-content: space-evenly;
align-items: flex-start;
}
.column {
width: 300px;
}
.col-child {
width: 100%;
margin-bottom: 10px;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
// 防抖
function debounce(fn, delay = 300) {
return () => {
var timer = null
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn()
}, delay)
}
}
// 生成随机数
function random(min, max) {
return Math.floor(Math.random() * (max - min)) + min
}
// 获取 element 的属性
function getElStyle(el, property) {
var elStyle = window.getComputedStyle(el)
var elProperty = elStyle.getPropertyValue(property)
return elProperty
}
// 获取数组最小值下标
function getMinIndex(arr) {
var min = Math.min(...arr)
var minIndex = arr.indexOf(min)
return minIndex
}
// 生成列
function generateColumn() {
// 获取瀑布流容器及宽度
var container = document.getElementById('container')
var containerWidth = getElStyle(container, 'width')
// 窗口大小变化时清空瀑布流 DOM 下的所有子节点
container.innerHTML = ''
console.log('瀑布流容器宽度', containerWidth)
// 计算列数
var column = Math.floor(parseInt(containerWidth) / 310)
console.log('列数', column)
if (column > 0) {
// 循环插入列
for (let i = 0; i < column; i++) {
var element = document.createElement('div')
element.className = 'column'
container.appendChild(element)
}
}
}
// 计算最低列并插入 DOM
function insertDom() {
// for 循环(插入30次)高度最矮的列,插入图片(没有图片我用元素代替)
for (let i = 0; i < 30; i++) {
// 创建要插入的瀑布块儿
var element = document.createElement('div')
// 定义瀑布块儿 className
element.className = 'col-child'
// 瀑布块儿高度,为了实现瀑布流效果随机生成(100 - 500)
var randomHeight = random(100, 500) + 'px'
element.style.height = randomHeight
var randomColor = `rgb(${random(0, 255)}, ${random(0, 255)}, ${random(0, 255)})`
element.style.backgroundColor = randomColor
// 获取所有列的 DOM (伪数组)
var allColumn = document.querySelectorAll('.column')
if (allColumn.length) {
// 转换成数组
var _allColumn = Array.prototype.slice.call(allColumn)
// 循环转换获取所有列的高度
var allColumnHeight = []
for (let i = 0; i < _allColumn.length; i++) {
allColumnHeight.push(parseInt(getElStyle(_allColumn[i], 'height')))
}
// 获取最小高度的下标
var minHeightIndex = getMinIndex(allColumnHeight)
// 最小高度列插入瀑布块儿
allColumn[minHeightIndex].appendChild(element)
}
}
}
// 窗口 change 事件
function init() {
generateColumn()
insertDom()
}
// window 的 onload 及 onresize 事件
window.onload = debounce(init)
window.onresize = debounce(init)
</script>
</body>
</html>