一起实现图片瀑布流

图片瀑布流

首先,什么是图片瀑布流?

如下图,现实中我们的图片宽高大小不是总是一致的,但是在既不想过分损失图片质量情况下,又能最大化利用空间,该怎么实现呢,一般有两种方案

一种是宽固定,高度自适应(每一列的宽度都是一样的,下图是三列),如下图:

该图片来自百度
___________________图片来源于百度,侵权请告知!_________________

一种是高固定,宽自适应(每一行高都是一样的,下图是三行),如下图:

在这里插入图片描述

很早之前就知道了图片瀑布流,但是一直没有想着去实现一个,今天一起来实现一下吧,锻炼我们的逻辑思维(以宽固定为例)

因为整体逻辑比较简单,所以直接在代码注释中解释了 ^ _ ^

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        body {
            background: #999;
        }
        
        * {
            margin: 0;
            padding: 0;
        }
        
        .all {
            background-color: rgba(255, 255, 255, 0.5);
            width: 1090px;/* 父元素的宽固定*/
            margin: auto;
            margin-top: 20px;/*整体到顶部的距离,为了好看点*/
            font-size: 0;/*消除图片间隙*/
            position: relative;/*给父级一个绝对定位,这样子元素就可以相对他定位*/
        }
        
        .smallimg {
            position: absolute;/*子元素开启相对定位*/
            width: 200px;/*子元素的宽固定为200*/
        }
    </style>
</head>

<body>
    <div class="all">

    </div>
    <script>
   		 //定义一个img数组,模仿图片数据源
        var img = ["01.jpg", "02.jpg", "03.jpg", "person.jpg", "pyy.jpg", "06.jpg", "03.jpg", "04.png", "05.jpg", "06.jpg"];
        var all = document.getElementsByClassName("all")[0];//先获取到瀑布流的父级元素
        var num = 5;//确定一行可以放多少个
        var total = 50;//初始要生成的图片数量
        //初始创建50张图片
        createEle(total);
        window.onload = function(ev) {
            //给50张图片设置定位
            setPosition(0);
            //获取页面的高并赋值
            var maxHeight = getMaxHeight(total);//获取创建完图片后的子元素的 总高(最上面的图片top到最下面的图片bottom),最大是多少,防止父级包不住
            all.style.height = maxHeight + "px";//把总高赋值给父级
        }

        function createEle(newTotal) {
            //创建对象函数
            for (var i = newTotal - 50; i < newTotal; i++) {
                var image = document.createElement("img");
                image.src = "images/" + img[Math.floor((Math.random() * num))];
                image.setAttribute("class", "smallimg"); //image.className = "smalling"
                all.appendChild(image);
            }
        }
		//关键函数,给图片设置定位
        function setPosition(start) {
            //设置图片定位函数
            for (var i = start; i < all.children.length; i++) {
            //因为子元素都是相对定位,所以设置偏移量就可以改变位置
            //i % num 表示的是  一行最多只放五个,现在这个图片是这一行的第 i % 5 个,num等于5不变
            // 知道是第几,那么左边的偏移量就是单个偏移的多少倍,比如第一个偏移 1 * 210 ,第二个偏移 2 * 210……
                all.children[i].style.left = ((i % num) * 210) + "px";
                // 当i > 5了,表示现在开始是第二行以后了,这时高度也高不断变化了,因为宽虽然固定,但是每个图片的高度不是一样的,要进行计算,再确定当前图片的应处于的高度
                if (i >= num) {
                //all.children[(i - num)].offsetHeight这个意思其实就是获取当前这个位置的 上面那张图片的高度
                // all.children[(i - num)].offsetTop这个意思是获取当前这个位置的 上面那张图片距离顶部的距离
                //再加上 间距10  就是应有的高度了
                    all.children[i].style.top = (all.children[(i - num)].offsetHeight + 10 + all.children[(i - num)].offsetTop) + "px";
                } else {
					//如果是第一行,那么高度就都是距离父级10px
                    all.children[i].style.top = "10px";
                }
            }
        }

        function getMaxHeight(newTotal) {
            //在创建完所有图片后获取all的最后十个子元素,并比较其自身高与距离顶部的高
            var max = 0
            for (var i = newTotal - 10; i < newTotal; i++) {
            // all.children[i].offsetTop 当前图片距离父级顶部的距离
            //all.children[i].offsetHeight当前图片的高度
                var temp = all.children[i].offsetTop + all.children[i].offsetHeight
                if (temp > max) {//在最后十张图片中,不断更新最大值
                    max = temp
                }
            }
            return max
        }

        this.addEventListener("scroll", function(evt) {
        	// document.documentElement.clientHeight可视区的高度
        	// document.body.offsetHeight 是body的总高度
            if (document.documentElement.clientHeight + this.scrollY >= document.body.offsetHeight - 20) {//经典滚动事件中的判断方法
                total = total + 50;//追加50张图片
                createEle(total);//再创建50张图片
                setPosition(total - 50)//设置后面50张的位置
                all.style.height = getMaxHeight(total) + "px";
            }

        });
    </script>
</body>

</html>

对于上我的理解,大家肯定有点晕,也不知道我说的是什么,那么就配合下面这个图一起理解吧!

在这里插入图片描述

瀑布流逻辑还是比较简单的,但是可以很好的锻炼我们的逻辑思维和加强对于js中的各种坐标的理解

有问题请私信哈!@ _ @

看都看完了,一键三连再走呗,嘿嘿嘿😁

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

summer·

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

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

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

打赏作者

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

抵扣说明:

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

余额充值