为了账号安全,请及时绑定邮箱和手机立即绑定

瀑布流布局

标签:
Html/CSS

什么是瀑布流布局

瀑布流布局的每列宽度相同,图片高度各不相同,随着页面滚动条往下滚动,会不断加载数据块并附加至最后。

实现思路

html

<!DOCTYPE html><html lang="en"><head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" href="./test.css">
    <!-- <script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="./test.js"></script> -->
    <script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="jquery-3.3.1.min.js"></script>
    <script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="./test1.js"></script></head><body>
    <div class="wrapper">
        <div class="box">
            <div class="pic"><img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="./img/1.png" alt="图片不存在"></div>
        </div>
        。。。。。。。// 此处很多个图片  
        <div class="box">
            <div class="pic"><img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="./img/50.png" alt="图片不存在"></div>
        </div>
    </div></body></html>

css

*{    margin: 0;    padding: 0}.wrapper{    position: relative;
}.wrapper .box{    position: absolute;    float: left;    padding: 0 10px 10px 10px; 
}.pic{  
    padding: 10px;    border: 1px solid #ccc;    border-radius: 5px;    box-shadow: 0 0 5px #ccc;  
}.pic img{    width: 200px;    height: auto;
}

原生js

window.  = function(){    /**
     *  步骤:
     *      1、页面加载时,就先加载出来
     *      2、当窗口改变时,再次调用waterFull()
     *      3、数据无限加载
     * 
     * 思路:
     *      1、计算窗口的宽度
     *      2、每个盒子的宽度
     *      3、列数为 步骤1/步骤2 向下取整
     *      4、布满第一行,将他们的高度放入arr中
     *      5、找到第一行最短的,值和index,将下一张图片放到最短的下边,更新arr,
     *      6、再次查找最短的,放入下一张图片,并更新arr,一直到最后
     *      7、计算滚动距离+一个屏幕的高度 与 最后一张图片距离顶端的高度 的差,以此来动态创建图片,
     *          加入到最后,每次加一张图片就调用一次 waterFull()
     */

    // 加载的时候先调用一次 
    var wrapper = document.getElementsByClassName('wrapper');    var box = document.getElementsByClassName('box');
    waterFull();    function waterFull(){        // 获取可视区宽度
        var pageWidth = getClient().width;        // 获取每张图片的宽度(总宽度)
        var boxWidth = box[0].offsetWidth;        // 计算一共有多少列
        var column = Math.floor(pageWidth / boxWidth);        // 定义数组,动态更新每一列的高度
        var arr = [];        for(var i=0;i<box.length;i++){            // 第一行
            if(i<column){
                box[i].style.top = 0;
                box[i].style.left = boxWidth*i + "px";
                arr.push(box[i].offsetHeight);                // console.log(arr);
            }else{                // 当是第二行,第三行。。。。
                // 求最短的高度
                var minHeight = Math.min.apply(null,arr);                // console.log(minHeight)
                // 求高度最短的索引
                var index = arr.indexOf(minHeight);
                box[i].style.top = minHeight + "px";
                box[i].style.left = index*boxWidth + "px";                // 更新arr
                arr[index] = arr[index] + box[i].offsetHeight;
            }
        }

    }    // 视口宽度改变时,重新计算
    window.onresize = function(){
        waterFull();
    }    // 获取可视区的宽高
    function getClient(){        return {            width : window.innerWidht || document.body.clientWidht || document.documentElement.clientWidth,            height : window.innerHeight || document.body.clientHeight || document.documentElement.clientHeight
        }
    }    // 获取滚动距离
    function getScrollTop(){        return window.pageYOffset || document.body.scrollTop + document.documentElement.scrollTop;
    }    // 模拟Ajax加载数据
    window.onscroll = function(){        // 滚动距离和最后一个box的高度比较
        var cha = getClient().height + getScrollTop() - (box[box.length-1].offsetTop);        var data = [            './img/0.png',            './img/1.png', 
            './img/2.png',            
            './img/3.png',            
            './img/4.png',            
            './img/5.png'
        ]        if(cha >= 0){            for(var i=0;i<data.length;i++){                var div = document.createElement('div');
                div.className = 'box';
                div.innerHTML = '<div class="pic"><img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="' + data[i] +'" alt="图片不存在"><div>';
                wrapper[0].appendChild(div);
                waterFull();
            }
        }   
    }
}

jQuery实现

window. = function(){

    waterFull();   /* 
    $(function(){})与window. = function(){}的区别
        $(function(){}) 是在页面渲染完之后调用的,这时候有一些图片资源等还没有下载完,就会出现图片的高度为0的情况

    window. = function(){}:表示在页面渲染完,并且资源加载完之后再执行的,

    所以如果要计算图片的高度,必须要等图片资源加载完,也就是要用第二种方式
   
   */   

    // 鼠标滚动事件   
    $(window).scroll(function(){
        loadImg();
    })    // 窗口大小改变事件
    $(window).resize(function(){
        waterFull();
    })
}// 瀑布流function waterFull(){    var box = $('.box')    // 可视区的宽度
    var pageWidth = $(window).width();    // console.log(pageWidth)
    // 每个元素的宽度
    var boxWidth = box.eq(0).outerWidth();    // console.log(boxWidth);
    var column = Math.floor(pageWidth/boxWidth);    // 一共有多少列
    // console.log(column);
    var arr = [];
    box.each(function(index, value){        if(index < column){
            $(value).css({                top : 0,                left : index*boxWidth + "px"
            })
            arr.push($(value).outerHeight());
        }else{            var minBox = Math.min.apply(null,arr);            var minBoxIndex = $.inArray(minBox, arr);
            $(value).css({                "top" : minBox,                "left" : minBoxIndex*boxWidth + "px"
            })
            arr[minBoxIndex] += $(value).outerHeight();
        }
    })
}// 无限加载数据function loadImg(){    var all = $(window).height() + $(window).scrollTop();    var lastBoxHeight = $('.box').last().get(0).offsetTop;    if(all>lastBoxHeight){        var data = [            './img/0.png',            './img/1.png', 
            './img/2.png',            
            './img/3.png',            
            './img/4.png',            
            './img/5.png'
        ]
        
        $.each(data,function(index,value){            var box = $("<div>").addClass("box").appendTo(".wrapper");            var content = $("<div>").addClass("pic").appendTo(box);
            $("<img>").attr("src",data[index]).appendTo(content);
        })
    }
    waterFull();
}

用到的知识点总结

1、$(function(){})window. = function(){}的区别
$(function(){})是在页面渲染完之后调用的,这时候有一些图片资源等还没有下载完,就会出现图片的高度为0的情况
window. = function(){}:表示在页面渲染完,并且资源加载完之后再执行的
所以如果想要得到全部的图片高度,就要等图片资源全部加载完再进行,也就是用第二种方式
2、$.inArray(minBox, arr) 得到minBox在arr中的位置



作者:椰果粒
链接:https://www.jianshu.com/p/272c4596c58e


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消