瀑布流布局

作者: 椰果粒 | 来源:发表于2018-07-30 21:58 被阅读19次

什么是瀑布流布局

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

实现思路

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" href="./test.css">
    <!-- <script src="./test.js"></script> -->
    <script src="jquery-3.3.1.min.js"></script>
    <script src="./test1.js"></script>
</head>
<body>
    <div class="wrapper">
        <div class="box">
            <div class="pic"><img src="./img/1.png" alt="图片不存在"></div>
        </div>
        。。。。。。。// 此处很多个图片
  
        <div class="box">
            <div class="pic"><img src="./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.onload  = 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 src="' + data[i] +'" alt="图片不存在"><div>';
                wrapper[0].appendChild(div);
                waterFull();
            }
        }   
    }
}

jQuery实现

window.onload = function(){

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

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

相关文章

  • 瀑布流布局 的学习

    1- 实现瀑布流布局效果 瀑布流效果瀑布流代码木桶布局效果木桶布局代码瀑布流布局 2- 实现一个新闻瀑布流新闻...

  • 瀑布流、木桶布局

    瀑布流 瀑布流效果代码 木桶布局 木桶布局效果(加载有点慢)代码

  • 瀑布流照片墙布局

    title: 瀑布流照片墙布局 瀑布流概念 瀑布流布局是错落式的布局方式。它有一个特点,整个布局以列为单位,下一个...

  • CSS经典布局

    圣杯布局 瀑布流

  • 瀑布流

    瀑布流布局瀑布流jsonp新闻页

  • 瀑布流布局_木桶布局

    题目1: 实现一个瀑布流布局效果 瀑布流 题目2:实现木桶布局效果 木桶布局 题目3:**实现一个新闻瀑布流新闻网...

  • 瀑布流和懒加载结合

    实现一个瀑布流布局效果 瀑布流

  • 瀑布流

    什么是瀑布流: 欣赏 pinterest 样式分析 瀑布流,又被称作为瀑布流式布局,是一种比较流行的网站页面布局方...

  • 瀑布流

    1、什么是瀑布流 瀑布流,又称瀑布流式布局。是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚...

  • 瀑布流的三种实现

    先来欣赏三个瀑布流的网站 pinterest 淘宝爱逛街 蘑菇街 什么是瀑布流? 瀑布流,又称瀑布流式布局。 这种...

网友评论

    本文标题:瀑布流布局

    本文链接:https://www.haomeiwen.com/subject/uvyqvftx.html