js原生实现瀑布流

使用position 排列图片,动态定位topleft

1. 确定浏览器显示区域内,一行放多少列图片盒子(图片宽度一致,高度由内容撑开);
1.1 获取页面宽度
1.2 获取图片盒子宽度
1.3 显示的列数 = 页面宽度 / 图片盒子宽度
2. 确定列数之后,先排列第一行
2.1 显示的列数 = 页面宽度/(图片盒子宽度+间隙);
2.2 for 循环里判断 当i (图片盒子的索引)小于column(列数)的时候,说明在第一行
2.3 知道在第一行之后,动态设置每个盒子的left 值来排列第一行
left = i * ( itemWidth + gap );
3. 第一行排好之后,获取第一行所有图片盒子的高度
3.1 定义一个空数组,放高度,第二行的top 值需要根据第一行的高度来设置
3.2 获取图片高度的时候要注意,程序必须写在入口函数onload里面,因为图片的加载特性是:等页面都加载完之后才去请求加载,所以不写在入口函数里可能会出现高度获取不到的情况。
4. 通过定位的方式排列第二行
4.1 获取到刚刚数组中,高度最小的那一列,将第2行的第1个图片盒子放置在它的下方;
4.2 此时的left值就是高度最小列的offsetLefttop值就是:第1行高度最小列的高度(为了布局美观可以加上上下间隙gap)。
4.3记录下高度最小列的索引index,后面计算会用到;
4.4 设置完成之后,会发现后面所有的图片都叠在这个高度最小列的下面,原因就是此时的最小列高度没有改变,应该加上下面图片的高度,得出一个新高度。
4.5 此时的这一列高度其实已经发生改变了,所以需要将新高度赋值给数组 当前高度最小列的高度 = 当前高度最小列的高度 + 间隙 + 下面图片盒子的高度
5. 触发resize事件
将整个设置样式的部分封装成一个函数,在onload里面注册一个resize事件,只要页面一发生改变,就触发样式部分的代码。实时改变pageWidth的宽度,这样瀑布流就会是一个响应式的效果了。
6.懒加载效果
6.1 目前我们用的是30张图片,假如一个页面中有几百张图片的时候,我们不可能等到它都加载完再显示,所有这里引入一个懒加载的概念,我们规定第30张为显示的最后一张图片,当滚动条滚动到30张的时候,应该加载下一批图片。
6.2 即页面可视区高度+滚动条卷去的高度 = 第30图片的offsetTop;的时候加载下面的图片。

代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            position: relative;
        }
        img {
            width: 220px;
            display: block;
        }
        .item {
           position: absolute;
            box-shadow: 2px 2px 2px #999999;
        }
    </style>
</head>
<body>
<div id="box">
<div class="item"><img src="images/1.jpg" alt=""></div>
<div class="item"><img src="images/2.jpg" alt=""></div>
<div class="item"><img src="images/3.jpg" alt=""></div>
<div class="item"><img src="images/4.jpg" alt=""></div>
<div class="item"><img src="images/5.jpg" alt=""></div>
<div class="item"><img src="images/6.jpg" alt=""></div>
<div class="item"><img src="images/7.jpg" alt=""></div>
<div class="item"><img src="images/8.jpg" alt=""></div>
<div class="item"><img src="images/9.jpg" alt=""></div>
<div class="item"><img src="images/10.jpg" alt=""></div>
<div class="item"><img src="images/11.jpg" alt=""></div>
<div class="item"><img src="images/12.jpg" alt=""></div>
<div class="item"><img src="images/13.jpg" alt=""></div>
<div class="item"><img src="images/14.jpg" alt=""></div>
<div class="item"><img src="images/15.jpg" alt=""></div>
<div class="item"><img src="images/16.jpg" alt=""></div>
<div class="item"><img src="images/17.jpg" alt=""></div>
<div class="item"><img src="images/18.jpg" alt=""></div>
<div class="item"><img src="images/19.jpg" alt=""></div>
<div class="item"><img src="images/20.jpg" alt=""></div>
<div class="item"><img src="images/21.jpg" alt=""></div>
<div class="item"><img src="images/22.jpg" alt=""></div>
</div>

<script>
    var box = document.getElementById("box");
    var items = box.children;
    var gap = 10;
    window.onload = function ( ) {
        waterFall();
        function waterFall() {
            var pageWidth = getClient().width;
            var itemWidth = items[0].offsetWidth;
            var columns = parseInt(pageWidth/(itemWidth + gap));
            var arr = [];
            for(var i = 0; i<items.length; i++){
                if (i < columns) {
                    items[i].style.top = 0;
                    items[i].style.left = (itemWidth + gap) * i + "px";
                    arr.push(items[i].offsetHeight);
                }else {
                    var minHeight = arr[0];
                    var index = 0;
                    for(var j = 0; j<arr.length; j++){
                        if(minHeight > arr[j]) {
                            minHeight = arr[j];
                            index = j;
                        }
                    }
                    items[i].style.top = arr[index] + gap +"px";
                    items[i].style.left = items[index].offsetLeft + "px";
                    arr[index] = arr[index] + items[i].offsetHeight + gap;
                }
            }
        }
        window.onresize = function () {
            waterFall();
        };
        window.onscroll = function ( ) {
            if (getClient().height + getScrollTop() >= items[items.length - 1].offsetTop) {
            //模拟ajax获取数据
                var datas = [
                    "images/1.jpg",
                    "images/2.jpg",
                    "images/3.jpg",
                    "images/4.jpg",
                    "images/5.jpg",
                    "images/6.jpg",
                    "images/7.jpg",
                    "images/8.jpg",
                    "images/9.jpg",
                    "images/10.jpg",
                    "images/11.jpg",
                    "images/12.jpg",
                    "images/13.jpg",
                    "images/14.jpg",
                    "images/15.jpg",
                    "images/16.jpg",
                    "images/17.jpg",
                    "images/18.jpg",
                    "images/19.jpg",
                    "images/20.jpg",
                    "images/21.jpg",
                    "images/22.jpg",
                ];
                for (var i = 0; i < datas.length; i++) {
                    var div = document.createElement("div");
                    div.className = "item";
                    div.innerHTML = '<img src="' + datas[i] + '" alt="">';
                    box.appendChild(div);
                }
                waterFall();
            }
        };
    };




    function getClient() {
        return {
            width:window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
            height:window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
        }
    }
    function getScrollTop() {
        return window.pageYOffset || document.documentElement.scrollTop;
    }
</script>
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值