这里为大家带来了两种通过js制作图片瀑布流的方法。
一、绝对定位法
计算每个元素的绝对位置进行设置。
<!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>瀑布流</title>
<style>
.image-item {
width: 300px;
position: absolute;
transition: all .5s;
}
.image-item .image {
width: 100%;
}
</style>
</head>
<body>
<div class="wrap">
<div class="image-item"><img src="./images/zj1.jpg" alt="" class="image"></div>
<div class="image-item"><img src="./images/zj2.jpg" alt="" class="image"></div>
<div class="image-item"><img src="./images/zj3.jpg" alt="" class="image"></div>
<div class="image-item"><img src="./images/zj4.jpg" alt="" class="image"></div>
<div class="image-item"><img src="./images/zj5.jpg" alt="" class="image"></div>
<div class="image-item"><img src="./images/zj6.jpg" alt="" class="image"></div>
<div class="image-item"><img src="./images/zj7.jpg" alt="" class="image"></div>
<div class="image-item"><img src="./images/zj8.jpg" alt="" class="image"></div>
<div class="image-item"><img src="./images/zj9.jpg" alt="" class="image"></div>
<div class="image-item"><img src="./images/zj10.jpg" alt="" class="image"></div>
<div class="image-item"><img src="./images/zj11.jpg" alt="" class="image"></div>
<div class="image-item"><img src="./images/zj12.jpg" alt="" class="image"></div>
<div class="image-item"><img src="./images/zj13.jpg" alt="" class="image"></div>
<div class="image-item"><img src="./images/zj14.jpg" alt="" class="image"></div>
<div class="image-item"><img src="./images/zj15.jpg" alt="" class="image"></div>
<div class="image-item"><img src="./images/zj16.jpg" alt="" class="image"></div>
<div class="image-item"><img src="./images/zj17.jpg" alt="" class="image"></div>
<div class="image-item"><img src="./images/zj18.jpg" alt="" class="image"></div>
</div>
</body>
<script>
const config = {
mode: 0,
marginHeight: 20,
}
window.onload = function() {
init();
}
function init() {
let {mode} = config;
config.imagesArray = document.querySelectorAll(".image-item");
const windowWidth = document.querySelector(".wrap").getBoundingClientRect().width; // 容器宽度
const imageWidth = config.imagesArray[0].getBoundingClientRect().width; // 单张图片宽度
config.imageWidth = imageWidth;
config.cols = parseInt(windowWidth/imageWidth); // 计算列数
//计算图片之间的间距(可选择space-between/space-around)
let spanNum = mode ? config.cols -1 : config.cols +1;
config.margin = (windowWidth - imageWidth * config.cols) / spanNum;
config.heightArray = (new Array(config.cols)).fill(0,0); //得到初始高度的数组
setImagePos();
}
function setImagePos() {
let { imageWidth, imagesArray, margin, heightArray, mode } = config;
imagesArray.forEach(item => {
//取高度数组中的最小值
let minHeight = Math.min.apply(Math.min, heightArray);
let currentIndex = heightArray.indexOf(minHeight);
// 设置图片位置
item.style.top = minHeight + "px";
if(mode) {
item.style.left = currentIndex * (imageWidth + margin) + "px";
} else {
item.style.left = currentIndex * (imageWidth + margin) + margin + "px";
}
//更新高度数组
let newHeight = item.getBoundingClientRect().height + config.marginHeight;
heightArray[currentIndex] += newHeight;
});
}
let timer;
window.onresize = function() {
clearTimeout(timer);
timer = setTimeout(init, 50);
}
</script>
</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>瀑布流2</title>
<style>
#wrap {
display: flex;
justify-content: space-around;
}
#wrap .col img {
width: 100%;
}
</style>
</head>
<body>
<div id="wrap"></div>
</body>
<script>
// 创建图片数组(由于图片名有规律,这里就不一个一个写)
const images = [];
for(var i = 1; i <= 18; i ++) {
var src = "./images/zj" + i + ".jpg";
images.push(src);
}
var wrap = document.getElementById("wrap");
var colWidth = 300; //每列宽度
var colsArray = []; // 列DOM数组
var heightArray = []; // 高度数组
var currentImage = 0; //图片索引
var oldCols = null; //用作记录,节约性能
var timer;
init();
window.onresize = function() {
clearTimeout(timer);
timer = setTimeout(function() {
init();
}, 50);
}
function init() {
// 得到对应的列数,并创建每列的容器
var windwoWidth = window.innerWidth;
var cols = parseInt(windwoWidth / colWidth);
if(cols !== oldCols) {
oldCols = cols;
//清空数据
colsArray = [];
heightArray = [];
currentImage = 0;
wrap.innerHTML = "";
// 创建列容器
for(var i = 0; i < cols; i++) {
var col = createElement("div",{"class":"col"});
colsArray.push(col);
wrap.appendChild(col);
heightArray.push(0);
}
//循环图片数据
pushImage();
}
}
function createElement(tagName,dataset) {
var tag = document.createElement(tagName);
for(key in dataset) {
tag.setAttribute(key,dataset[key]);
}
return tag;
}
function pushImage(dataset) {
var dataset = {
"src": images[currentImage]
};
var image = createElement("img",dataset);
var min = Math.min.apply(Math.min, heightArray);
var currentIndex = heightArray.indexOf(min);
colsArray[currentIndex].appendChild(image);
image.onload = function() {
// 当图片达到最大时,不执行
if(currentImage < images.length -1 ) {
// 计算加入图片后的容器高度
var imageHeight = image.getBoundingClientRect().height;
console.log(image.getBoundingClientRect())
heightArray[currentIndex] += imageHeight;
// 图片索引累加
currentImage ++;
pushImage();
} else {
return false;
}
}
}
</script>
</html>
知识兔当然肯定还有比这个好的方法,仅作学习交流。
ps:图片存放地址为 当前目录的images目录里面