头图

所谓瀑布流就是让大小尺寸不同的图片像瀑布一样,整个页面都布满图片

而在Ajax中,瀑布流可以说是很常见的,利用瀑布流无限加载技术,取消了分页按钮,鼠标滑动到底部会自动加载图片

先上一下效果图:

img

html结构 和 css样式

<head>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        img {
            width: 250px;
            position: absolute;
            display: block;
            transition: 0.8s;
        }
    </style>

    <body>
        <!-- 页面一上来先加载一些图片 -->
        <img src="图片1" alt="">
        <img src="图片2" alt="">
        <img src="图片3" alt="">
        <img src="图片4" alt="">
        <img src="图片5" alt="">
        <img src="图片6" alt="">
        <img src="图片7" alt="">
        <img src="图片8" alt="">
        <img src="图片9" alt="">
    </body>
</head>

Ajax

这个一个重点就是使用 imgH这个数组来存储每一列的图片高度,高度小的先排列,就会形成瀑布流

<script src="./server1/public/js/Ajax.js"></script>
<script>
    // 页面加载完成就调用layout进行布局
    window.onload = layout;
    // 窗口改变也调用函数
    window.onresize = function() {
        layout();
    }

    function layout() {
        // 获取全部的图片
        let getImgs = document.querySelectorAll('img');
        // 获取可视区的宽度
        let windowWidth = document.documentElement.clientWidth;
        // 计算一行显示多少张图片
        let n = Math.floor(windowWidth / 350);
        if (n <= 0) {
            return
        }

        // 计算页面两侧的空白
        let blankWidth = (windowWidth - n * 250) / 2
        // imgH 用来记录每一列的图片高度
        let imgH = []
        for (let i = 0, n1 = getImgs.length; i < n1; i++) {
            // 用来计算是是一行中的第几个img,给数组作索引
            let j = i % n;
            if (imgH.length === n) {
                // 从高度低的开始排
                let min = getMin(imgH);
                // 左右上下定位,并给一个20px的间距
                getImgs[i].style.left = blankWidth + min * 270 + 'px'
                getImgs[i].style.top = imgH[min] + 20 + 'px'

                // 修改该位置的图片的高度
                imgH[min] = imgH[min] + getImgs[i].offsetHeight + 20
            } else {
                // 这个用来排序第一行,把img的高度放进数组
                imgH[i] = getImgs[i].offsetHeight + 20;
                // 左右定位
                getImgs[i].style.left = blankWidth + j * 270 + 'px';
                getImgs[i].style.top = 20 + 'px';
            }
        }
    }

    // 找出高度最小的图片的索引
    function getMin(arr) {
        let m = 0
        for (let i = 0, n = arr.length; i < n; i++) {
            m = Math.min(arr[m], arr[i]) === arr[m] ? m : i;
        }
        return m;
    }
    
    // j 用来记录Ajax请求的次数
    let j = 0
    // 当滚动条滚动时触发函数
    window.onscroll = function() {
        // 可视区高度
        let windowHeight = document.documentElement.clientHeight;
        // 被卷去的高度
        let windowScroll = document.documentElement.scrollTop || document.documentElement.scrollTop;
        // 图片高度
        let imgsHeight = document.documentElement.scrollHeight;
        
        // 判断是否到底部了,是就通过Ajax请求发送数据
        if (windowHeight + windowScroll >= imgsHeight - 20) {
            if (j < 4) {
                Ajax({
                    url: 'http://127.0.0.1:3000/getImg',
                    // 将j传给服务器端
                    data: {
                        num: j
                    },
                    success(data) {
                        data = JSON.parse(data)
                        for (let key in data) {
                            // 创建图像标签
                            let img = document.createElement('img');
                            // 绑定标签
                            img.src = data[key];
                            document.body.appendChild(img)
                        };
                        // 追加新的节点之后重新布局
                        layout();
                    }
                });
                j++
            } else {
                layout()
            }
        };
    };
</script>

这里的j 其实是用来控制Ajax请求的次数的,这里只进行4次请求(没有那么多图片),当然如果你去掉判断条件,就可以实现无限加载啦

这里的服务端比较简单,只是响应图片而已

app.get('/getImg', function(req, res) {
    res.setHeader('Access-Control-Allow-Origin', '*');
    // 准备了4个图片库
    imgsUrl1 = {},
    imgsUrl2 = {},
    imgsUrl3 = {},
    imgsUrl4 = {}
    // 每次请求发送一个图库
    if (req.query.num === '0') {
        res.json(imgsUrl1)
    } else if (req.query.num === '1') {
        res.json(imgsUrl2)
    } else if (req.query.num === '2') {
        res.json(imgsUrl3)
    } else {
        res.json(imgsUrl4)
    }
})

才疏学浅,只能实现这点东西(呜呜呜呜....),若有差错,还望指出,继续冲啊啊啊啊啊啊!


蝼蚁之行
31 声望1 粉丝

日益努力然后风声水起