瀑布流软加载

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        body {
            background: #f1f1f1;
        }

        img {
            display: block;
        }

        .waterfall .box {
            padding-right: 10px;
            padding-bottom: 10px;
            position: absolute;
            transition: left .5s, top .5s;
            /* background: white; */
        }

        .waterfall .box img {
             250px;
        }

        .waterfall .box p {
            background: white;
            height: 30px;
            line-height: 30px;
        }

        .waterfall .box p span {
            font-size: 12px;
            color: #666;
        }

        .waterfall .box p a {
            font-size: 12px;
            color: #444;
            text-decoration: none;
        }

        .waterfall .box p a:hover {
            background: #e5461c;
            color: #fff;
        }
    </style>
</head>

<body>
    <div class="waterfall">
        <!-- (div.box>img[src="./imgs/pic ($).jpg"]+p>span{标签:}+a{明星})*50 -->
        <div class="box">
            <img src="./imgs/pic (111).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (2).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (3).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (4).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (5).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (6).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (7).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (8).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (9).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (10).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (11).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (12).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (13).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (14).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (15).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (16).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (17).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (18).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (19).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (20).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (21).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (22).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (23).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (24).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (25).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (26).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (27).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (28).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (29).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (30).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (31).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (32).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (33).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (34).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (35).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (36).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (37).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (38).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (39).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (40).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (41).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (42).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (43).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (44).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (45).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (46).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (47).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (48).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (49).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>
        <div class="box">
            <img src="./imgs/pic (50).jpg" alt="">
            <p><span>标签:</span><a href="">明星</a></p>
        </div>

    </div>

    <script>
        function waterfall() {
            //取得所有盒子
            var boxes = document.querySelectorAll('.waterfall .box');
            var boxW = boxes[0].offsetWidth
            var col = Math.floor(window.innerWidth / boxW);
            var heightArray = [];

            for (var i = 0; i < boxes.length; i++) {
                if (i < col) {
                    //第一行
                    boxes[i].style.top = 0;
                    boxes[i].style.left = i * boxW + 'px'
                    heightArray.push(boxes[i].offsetHeight);
                } else {
                    //其他行
                    //  1. 找到数组的最小值
                    //      使用展开运算符...,将nums展开,之后,传递给Math.min(),就可以取得最小高度
                    var minH = Math.min(...heightArray);
                    var minIndex = heightArray.indexOf(minH);

                    boxes[i].style.top = minH + 'px'
                    boxes[i].style.left = minIndex * boxW + 'px'

                    heightArray[minIndex] = minH + boxes[i].offsetHeight;


                }
            }

            console.log(heightArray)
        }

        //页面大小改变,或者是zoom改变时,会触发onresize
        window.onresize = window.onload = function () {
            //在这个事件中调用waterfall()可以保证布局发生在所有的图片下载完成之后。
            waterfall()
        }

        window.onscroll = function () {
            if (needLoad()) {
                //加载数据
                loadData();
            }
        }

        function needLoad() {
            //返回true需要加载,返回false不需要
            let lastBox = document.querySelector('.box:last-of-type');

            //取得这个盒子距离可视区顶端的距离
            let dist = lastBox.getBoundingClientRect().y
            // return dist<= window.innerHeight ? true : flase
            return dist <= window.innerHeight
        }

        var start;

        function loadData() {
            //ajax获取数据
            var now = new Date();   //每次调用loadData,都取得一个当前时间
            if (!start || now - start > 1000) {
                //start等于未定义,就是这第一次调用loadData
                start = now;    //计时开始
                
                let xhr = new XMLHttpRequest();

                xhr.open('get', './imgs.json', true)

                xhr.onload = function () {
                    if (this.status >= 200 && this.status < 300) {
                        //取得数据
                        // console.log(this.responseText)
                        let imgs = JSON.parse(this.responseText)

                        //直接在修改完DOM树后,调用waterfall(),会因为图片还没下载完成导致布局的错误。
                        //我们需要等待这30张图片加载完成,再调用waterfall
                        //我们只需要监听每个图片加载完成的事件,并在时间中对计数器进行自增。
                        //当计数器数值等于了图片总个数,说明全部加载完成。此时可以调用waterfall()
                        var counter = 0;

                        imgs.forEach(img => {
                            let pic = new Image();  //创建一个图片对象
                            pic.src = img.src;      //将图片对象的src进行了赋值。一旦给图片对象的src赋值,浏览器就会开始下载图片

                            pic.onload = function () {
                                //图片下载完成时,会触发该事件
                                counter++;
                                if (counter === imgs.length) {
                                    waterfall();
                                }
                            }
                            pic.onerror = function () {
                                //图片下载失败,会触发这个事件
                                counter++;
                                if (counter === imgs.length) {
                                    waterfall();
                                }
                            }
                        })

                        let boxes = imgs.map(obj => `
                        <div class="box">
                            <img src="${obj.src}" alt="">
                            <p><span>标签:</span><a href="">明星</a></p>
                        </div>
                    `)
                        boxes = boxes.join('');
                        // console.log(boxes);
                        document.querySelector('.waterfall').innerHTML += boxes;


                        // waterfall();
                    } else {
                        //出错了
                    }
                }

                xhr.send()
            }
            //根据数据创建div.box的节点
        }

    </script>

</body>

</html>
原文地址:https://www.cnblogs.com/plmmq/p/11707804.html