完整瀑布流布局-手撸原生js实现瀑布流-附上完整js代码拿来即可用-列数自适应网页窗口大小-并走了节流

瀑布流

什么是瀑布流:等宽不等高的样式在网页中按照一定的规则去排列
实现原理:先根据窗口宽度和等宽div的大小计算出列数,然后先给第一行的div进行布局,第 一行布局完毕再去布局第二行,但是第二行的第一个元素放在哪呢?要放在第一行的最短的div下方!!css的布局走定位去实现,然后根据js的判断去设置每个div的top和left值。

主要是网上的这些资料太杂了,看半天都是介绍,或者是展示个核心代码,我相信来搜这个的兄弟们肯定是想有个能直接运行的例子,所以就来个干货,代码中的onresize走了截流~后面继着这个代码会完善个图片的懒加载,想看js实现懒加载效果的可以去我后面一篇看

具体怎么实现,直接放代码,里面每一步都有详细的解释。
你只需新建个.html文件,然后将代码复制进去运行即可(其中有图片的路径,改一下成你的图片路径)

<!DOCTYPE html>
<br lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
    <title>Title</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        #box{
            position: relative;
        }
        #box .item{
            position: absolute;
            width: 300px;
        }
        #box .item img{
            width: 100%;
        }
    </style>
</head>

<body>

<!--瀑布流实现-->
<div id="box">
    <div class="item">
        <img src="./image/p1.jpeg" alt="">
    </div>
    <div class="item">
        <img src="./image/p4.jpeg" alt="">
    </div>
    <div class="item">
        <img src="./image/p3.jpeg" alt="">
    </div>
    <div class="item">
        <img src="./image/p2.jpeg" alt="">
    </div>
    <div class="item">
        <img src="./image/p3.jpeg" alt="">
    </div>
    <div class="item">
        <img src="./image/p4.jpeg" alt="">
    </div>
    <div class="item">
        <img src="./image/p2.jpeg" alt="">
    </div>
    <div class="item">
        <img src="./image/p1.jpeg" alt="">
    </div>
</div>

<script>
    //瀑布流实现
    function waterImg(){
        let box = document.getElementById('box');
        let items = box.children;//包裹图片的div类数组
        let clientWidth =getClient().width;
        let columnNums =parseInt(clientWidth/300); //根据网页可视宽度计算一行的列数
        let leftWeight = 10;
        let oneColumsHeight = [];//存储第一列图片的高度--为了计算后面列数图片的排列情况
        for(let i=0;i<items.length;i++){
            if(i<=columnNums-1){//这里判断是否是第一行的图片--根据列数和下标来对比
                items[i].style.left=i*(300+leftWeight)+'px';
                //浏览器从小到大拉伸--这里要设置
                items[i].style.top = 0 + 'px';
                oneColumsHeight.push(items[i].offsetHeight);//offsetWidth = width + padding + border, 和margin无关。
            }else{
                //先找到存储第一列高度数组里面最小的那个高度数据
                let minHeight = oneColumsHeight[0];
                let index = 0;
                for(let j = 0;j<oneColumsHeight.length;j++){
                    if(minHeight>oneColumsHeight[j]){
                        minHeight = oneColumsHeight[j];
                        index = j
                    }
                }
                //找到过后给这个图片的top-left属性进行赋值(因为不是第一行了--top属性要进行赋值)
                items[i].style.top = oneColumsHeight[index]+leftWeight + 'px';
                items[i].style.left = items[index].offsetLeft+'px';
                //然后这里--因为oneColumsHeight中最短的那个height下面已经加了一张图片了--所以这里要给最短的height的值进行增加(增加的高度为新加的那张图片的高度)
                // console.log(items[i].offsetHeight)
                oneColumsHeight[index] = oneColumsHeight[index]+items[i].offsetHeight + leftWeight;
            }
        }
        //获取视口宽度--高度方法
        function getClient() {
            return {
                width:window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
                height:window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight,
            }
        }
    }
    //加载时触发
    window.onload= waterImg;
    //浏览器视口改变触发
    window.onresize = throttle(500);
    //闭包实现截流
    function throttle(wait) {
        let timer;
        return function () {
            if (!timer){
                timer = setTimeout(function () {
                    waterImg();
                    timer = null;
                },wait);
            }

        }
    }
</script>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吴大大逛博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值