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目录里面

posted @ 2019-10-11 10:18  本该如此  阅读(964)  评论(0编辑  收藏  举报