JS图片瀑布流制作
这里为大家带来了两种通过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目录里面