技术要求:
1. 所有的图片适用绝对定位
2. 使用JS设置图片的位置
3. 要求所有的图片等宽
图片的异步加载问题:
当图片设置了src属性之后,不会同步完成图片加载,而是异步(不影响当前代码的执行)
图片中有onload事件,该事件是图片加载完成之后触发。
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
#water {
position: relative;
width: 90%;
margin: 0 auto;
outline: 1px solid;
overflow: hidden;
}
#water img {
transition: all .5s;
}
</style>
</head>
<body>
<div id="water">
</div>
<script src="./scripts/waterfall.js"></script>
<script>
var div = document.getElementById("water");
//包含图片路径的数组
var imgs = [];
for (var i = 0; i <= 40; i++) {
imgs.push("img/" + i + ".jpg");
}
createWaterFall(div, imgs, 220);
</script>
</body>
</html>
waterfall.js
function createWaterFall(areaDom, urls, everyWidth) { //容器dom, 图片地址数组, 图片宽度
var colNumber; //有多少列
var gap; //每一列之间的间隙
//1. 创建图片
createImgDoms();
//2. 设置图片的坐标
setImgPosition();
//窗口改变事件
var timer = null;
window.onresize = function () {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(function () {
setImgPosition();
}, 500);
}
//函数区
/**
* 计算一些小学数学问题
*/
function cal() {
var containerWidth = parseInt(areaDom.clientWidth);
colNumber = Math.floor(containerWidth / everyWidth);
//剩余空间
var space = containerWidth - colNumber * everyWidth;
gap = space / (colNumber + 1);
}
/**
* 创建图片的dom对象
*/
function createImgDoms() {
for (var i = 0; i < urls.length; i++) {
var url = urls[i];
var img = document.createElement("img");
img.src = url;
img.style.width = everyWidth + "px";
img.style.position = "absolute";
img.onload = function () {
setImgPosition();
}
areaDom.appendChild(img);
}
}
/**
* 设置每张图片的坐标
*/
function setImgPosition() {
cal();
var colY = new Array(colNumber); //存放的是每一列的下一个图片的Y坐标
colY.fill(0); //将数组的每一项填充为0
for (var i = 0; i < areaDom.children.length; i++) {
var img = areaDom.children[i];
//找到colY中的最小值
var y = Math.min.apply(null, colY);//y坐标
//x坐标
var index = colY.indexOf(y) //第几列
var x = (index + 1) * gap + index * everyWidth;
img.style.left = x + "px";
img.style.top = y + "px";
//更新数组
colY[index] += parseInt(img.height) + gap;
}
//找到数组中最大的数字
var height = Math.max.apply(null, colY);
areaDom.style.height = height + "px";
}
}