HTML
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>瀑布流布局</title>
<link rel="stylesheet" href="/common/css/reset.css" />
<link rel="stylesheet" href="./index.css" />
</head>
<body>
<h1>瀑布流布局</h1>
<div class="container"></div>
<script src="./index.js"></script>
</body>
</html>
CSS
h1 {
font-size: 30px;
text-align: center;
margin-top: 50px;
}
.container {
width: 90%;
margin: 0 auto;
margin-top: 30px;
position: relative;
min-height: 800px;
}
.item {
width: 200px;
background-color: #ccc;
float: left;
border-radius: 6px;
position: absolute;
transition: all 0.3s;
}
JS
function $(selector) {
return document.querySelector(selector);
}
function $$(selector) {
return document.querySelectorAll(selector);
}
var doms = {};
var columnHeights = [];
init();
function layout() {
console.log('layout');
function calColumns() {
var containerWidth = doms.container.clientWidth;
var itemWidth = 200 || doms.waterFallItems[0].clientWidth;
var columns = Math.floor(containerWidth / itemWidth);
var gap = (containerWidth - columns * itemWidth) / (columns - 1);
if (gap < 10) {
columns -= 1;
gap = (containerWidth - columns * itemWidth) / (columns - 1);
}
columnHeights = new Array(columns).fill(0);
return {
columns,
gap
}
}
function getColumnIndex() {
var minHeight = Math.min(...columnHeights);
return columnHeights.indexOf(minHeight);
}
function setItemPosition(item, columnIndex) {
function setLeft() {
item.style.left = columnIndex * (200 + gap) + 'px';
}
function setTop() {
item.style.top = columnHeights[columnIndex] + 'px';
columnHeights[columnIndex] += item.clientHeight + 30;
}
setLeft();
setTop();
}
var { columns, gap } = calColumns();
console.log('columns', columns, 'gap', gap);
var containerWidth = doms.container.clientWidth;
console.log('containerWidth', containerWidth);
console.log(columns * 200 + (columns - 1) * gap);
for (let i = 0; i < doms.waterFallItems.length; i++) {
var item = doms.waterFallItems[i];
var columnIndex = getColumnIndex();
setItemPosition(item, columnIndex);
}
function setContainerHeight() {
var maxHeight = Math.max(...columnHeights);
doms.container.style.height = maxHeight + 'px';
}
setContainerHeight();
}
function init() {
doms.container = $('.container');
for (let i = 0; i < 20; i++) {
var item = createItem();
doms.container.appendChild(item);
}
doms.waterFallItems = $$('.item');
layout();
window.addEventListener('resize', debounce(layout, 200));
}
function createItem() {
function getRandomColor() {
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
function getRandomHeight() {
return Math.floor(Math.random() * 200) + 100;
}
var item = document.createElement('div');
item.setAttribute('class', 'item');
item.style.backgroundColor = getRandomColor();
item.style.height = getRandomHeight() + 'px';
return item;
}
function debounce(fn, delay) {
let timer = null;
return function (...args) {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
}
}