手写瀑布流

之前用vue-masonry实现瀑布流
在这里插入图片描述

<!DOCTYPE html>
<html>

<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">

    <title>自适应瀑布流布局</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .container{
            width: 90%;
            margin: 0 auto;
            position: relative;
        }
        .container img{
            position: absolute;
            transition: 0.3s;
        }
    </style>
</head>

<body>
<div class="container"></div>
</body>

</html>

<script>
    // 容器
    const container=document.querySelector('.container');
    let img_width=220; //每张图片的固定宽度

    // 加入图片元素
    function createImgs(){
        for(let i=1;i<=15;i++){
            // 生成图片的src路径(图片名为:1~15.jpg)
            let src='https://picsum.photos/200/300?r='+i;
            let img=document.createElement('img');
            img.src=src;
            img.width=img_width;
            // 每一张图片加载完就设置位置
            img.onload=setPositions;
            // 将图片添加到容器中
            container.appendChild(img);
        }
    }

    // 多加入一下图片
    createImgs();
    createImgs();
    createImgs();
    createImgs();

    // 计算一共有多少列,以及每一列之间的间隙
    function cal(){
        // 容器宽度
        let container_width=container.clientWidth;
        // 计算列的数量
        let columns=Math.floor(container_width/img_width);
        // 计算间隙
        let space_number=columns+1; //间隙的数量
        let left_space=container_width-columns*img_width; //计算剩余的空间
        let space=left_space/space_number; //每个间隙的空间
        return {
            space: space,
            columns: columns
        };
    }

    // 设置每张图片的位置
    function setPositions(){
        // 获取列数和间隙
        let info=cal();
        // 该数组的长度为列数,每一项表示该列的下一个图片的纵坐标
        let next_tops=new Array(info.columns);
        // 将数组的每一项填充为0
        next_tops.fill(0);
        for(let i=0;i<container.children.length;i++){
            let img=container.children[i];
            // 找到next_tops中的最小值作为当前图片的纵坐标
            let min_top=Math.min.apply(null,next_tops);
            img.style.top=min_top+'px';
            // 重新设置数组这一项的下一个top值
            let index=next_tops.indexOf(min_top); //得到使用的是第几列的top值
            next_tops[index]+=img.height+info.space;
            // 计算横坐标
            let left=(index+1)*info.space+index*img_width;
            img.style.left=left+'px';
        }
        // 得到next_tops中的最大值
        let max=Math.max.apply(null,next_tops);
        // 设置容器的高度
        container.style.height=max+'px';
    }

    // window.οnlοad=setPositions;
    // 定时器
    let timer=null;
    // 窗口尺寸变动后,重新排列,防抖
    window.onresize=function(){
        if(timer){
            clearTimeout(timer);
        }
        timer=setTimeout(setPositions,100);
    }
</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值