2021-05-02 瀑布流的多种实现方式

一.CSS实现瀑布流
代码
<style>
/* 多列布局写瀑布流:*/
*{margin: 0;padding: 0;}
        body{
            background: url(images/a.png),#000 url(images/bg.gif);
            
        }
        .content{
            column-count:10;
        }
        figure{
            border: 2px solid white;
            padding: 10px 0px;
            color: white;
            text-align: center;
            break-inside: avoid;
        }
        figure img{
            width: 100%;
        }
        figcaption{
            font-size: 35px;
            text-align: center;
        }
</style>

<body>
  <div class="content">
    <!--  快捷键:figure*50>img[src="images/$.png"] -->
    <figure><img src="../images/1.jpg" alt=""><figcaption>往后余生,风雪是你</figcaption></figure>
...2~39略...
    <figure><img src="../images/40.jpg" alt=""><figcaption>往后余生,风雪是你</figcaption></figure>
</div>>

</body>
二.JS实现瀑布流

主要思路:

若图片索引小于列数:
     正常输出,
     并用一个空数组记录第一行每张图片的高度

若图片索引大于列数:
     先找出高度数组的最小值,并在最短图片的下方添加图片
     更新其高度(此时新的最短图片出现了)
     重复以上步骤

1.面向过程的瀑布流
代码:
<body>
    <div id="box">
        <!-- 快捷键:img[src="../images/$.jpg" width="220px"]*40  -->
        <img width="220px" src="../images/1.jpg" alt="">
...
        <img width="220px" src="../images/40.jpg" alt="">
    </div>
</body>
<script>
    /*需要图片加载完才能获取到其高度*/
    window.onload = function() {
        //1.获取节点
        var imgs = document.querySelectorAll("img");
        //2.获取当前页面与图片的宽度.并由此得出列数
        /*图片宽度都是一样的*/
        var clientW = document.body.clientWidth;
        var imgW = imgs[0].offsetWidth;
        var column = parseInt(clientW / imgW);
        //3.设置左边距
        var marL = 10;

        //4.追加图片
        //设置一个空数组接收首行图片高度
        var arrH = [];
        for (var i = 0; i < imgs.length; i++) {
            //第一行:正常显示并记录每张图片的高
            if (i < column) {
                imgs[i].style.left = (imgW + marL) * i + 'px';
                // imgs[i].style.top = 0 + 'px';
                arrH.push(imgs[i].offsetHeight);
            }
            //非第一行:不断地在最短图片下方添加新图片并更新其高度
            else {
                //找出最小高度L先假设一个最小高度白让其不断与数组元素对比,
                //若有前者大于后者的情况则让前者等于后者
                var minH = arrH[0],
                    index = 0;
                for (var j = 0; j < arrH.length; j++) {
                    if (minH > arrH[j]) {
                        minH = arrH[j];
                        index = j;
                    }
                }
                //在最短图片下方追加图片
                imgs[i].style.left = imgs[index].offsetLeft + 'px';
                imgs[i].style.top = minH + 'px';
                //更新图片高度(实际上就是其所在列的总高度)
                arrH[index] = minH + imgs[i].offsetHeight;
            }
        }
    }
</script>
2.面向对象的瀑布流
代码:
<style>
    * {
        position: relative;
    }
    
    img {
        display: block;
        width: 220px;
    }
    
    #box {
        margin: 0 auto;
    }
    
    .item {
        box-shadow: 2px 2px 2px #999999;
        position: absolute;
    }
</style>

<body>
    <div id="box">
        <!-- <img src="../images/1.jpg" alt="" srcset=""> -->
    </div>
</body>
<script>
    // 瀑布流思路:css固定每张图宽度=>
    // 加载第一行记录每张图片的高度=>在最短图片下方添加图片
    class WaterFall {
        constructor() {
            // 节点
            this.boxObj = document.getElementById("box");
            this.imgsObj = document.querySelectorAll("img");
            this.appendImg(); //创建和追加节点
            // 列数
            this.cliW = document.body.clientWidth;
            // this.imgW = imgsObj[0].offsetWidth;
            this.imgW = 220;
            this.columns = parseInt(this.cliW / this.imgW);
            // 间隙
            this.leftM = 10;
            this.topM = 10;
            // 加载
            let that = this;
            window.onload = function() {
                    that.sortImg();
                    that.lazyLoad();
                }
                // that.sortImg();
        }
        appendImg() {
            for (var i = 1; i <= 40; i++) {
                var imgObj = document.createElement("img");
                Object.assign(imgObj, {
                    className: "item",
                    src: "../images/" + i + ".jpg"
                })
                this.boxObj.appendChild(imgObj);
            }
        }
        sortImg() {
            // 设置一个空数组存放图片高度
            let lineHe = [];
            // 遍历图片,判断是否是第一行图片
            this.imgsObj = document.querySelectorAll("img");
            this.imgsObj.forEach((v, k) => {
                if (k < this.columns) { //第一行
                    v.style.left = (this.imgW + this.leftM) * k + "px";
                    lineHe.push(v.offsetHeight);
                } else { //非第一行
                    // 找出最短图片
                    var minIndex = 0;
                    var min = imgsObj[minIndex];
                    this.lineHe.forEach((val, key) => {
                        if (min > key) {
                            min = key;
                            minIndex = val;
                        }
                    });
                    // 在最短图片下添加新图片
                    v.style.left = this.imgsObj[minIndex].offsetLeft + "px"; //确定新图片水平方向的位置
                    v.style.top = min + this.top + 'px';
                    // 添加图片后更新其高度
                    lineHe[minIndex] = lineHe[minIndex] + v.offsetHeight + this.topM;
                }
            })
        }
    }
    new WaterFall;
</script>
3.无限加载的瀑布流
 class WaterFall {
        constructor() {
   ...
            window.onload = function() {
                    that.sortImg();
                    that.lazyLoad();
                }
            
        }
     ...
        lazyLoad() {
            let imgArr = ['../images/11.jpg', '../images/14.jpg', '../images/17.jpg', '../images/12.jpg', '../images/18.jpg', '../images/19.jpg'];
            // 可视区高度
            let cliH = document.body.clientHeight;
            // 内容高度=最后一张图片的offsetTop(距离父元素body顶部的距离)
            let contentH = this.imgsObj[this.imgsObj.length - 1].offsetTop;
            // 滑动滚动条,当可视区高度+滚动条高度>内容高度时,加载新数据
            let that = this;
            wondow.onsrcoll = function() {
                // 滚动调高度(滚动距离)
                let st = document.documentElement.scrollTop;
                if (st + cliH > contentH) {
                    imgArr.forEach(v => {
                        let imgObj = document.createElement("img");
                        Object.assign(imgObj, {
                            className: "item",
                            src: v
                        })
                        that.boxObj.appendChild(imgObj);
                    })
                    that.sortImg();
                }
            }
        }
    }
三.Vue实现简单瀑布流
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

前端OnTheRun

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

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

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

打赏作者

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

抵扣说明:

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

余额充值