three way of waterfall flow

First the simple way , use css3 colum-width:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>


    <style>

        ul{
            column-width: 250px;
        }

        ul>li{
            display: inline-block;
            box-shadow: 10px 10px 10px 10px gray;
            background: red;
            width: 100%;
            height: 300px;
            text-decoration: none;
            margin: 10px 0;
        }

        ul>li:nth-of-type(1){
            height: 100px;
        }

        ul>li:nth-of-type(2){
            height: 50px;
        }

        ul>li:nth-of-type(3){
            height: 80px;
        }


        ul>li:nth-of-type(4){
            height: 120px;
        }


        ul>li:nth-of-type(5){
            height: 180px;
        }

        ul>li:nth-of-type(6){
            height: 200px;
        }

        ul>li:nth-of-type(7){
            height: 111px;
        }


    </style>
</head>
<body>
<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
</ul>
</body>
</html>

這裏寫圖片描述

note : you need add display:inline-block otherwise some block will to next colum.

the second way ,by javascript

step:

    .1 dynatic create box and img 
    .2 cycle get the minimum height and then put the next to the below of the most minimum  use position absolute method
    .3 when scroll to half height of screen load other more 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>瀑布流首頁</title>

    <style>

        *{
            /*去除邊距*/
            margin:0;
            padding: 0;
            /*html性能優化:虛擬dom,如果一個html標籤沒有設置css樣式,就是虛擬的,
             所以無論設置多少層div都對性能沒有影響*/
        }
        #main{
            height: 2000px;
            /*定位*/
            position: relative;
        }
        .box{
            /*內邊距*/
            padding:15px 0 0 15px ;
            float: left;
        }
        .pic{
            /*邊框*/
            border:1px solid #dddddd;
        }
        .pic img{
            width: 105px;
        }

    </style>
</head>
<body>
<!--父盒子-->
<div id="main">
    <!--單個盒子-->
    <div class="box">
        <!--圖片盒子-->
        <div class="pic">
            ![](images/1.jpg)
        </div>
    </div>
    <!--單個盒子標籤複製20次...圖片名字改改...-->
</div>
<!--jQuery方式需要引入jQuery庫,JS方式與CSS方式都要註釋掉-->
<!--引入JS,CSS方式註釋掉-->

<script>


    /**
     * Created by Mac on 2017/1/7.
     */
    function $(id) {
        //判斷id的類型
        return typeof id === 'string'?document.getElementById(id):id;
    }

    //當網頁加載完畢
    window.onload = function () {
        //瀑布流佈局 保證傳的參數能夠找到父盒子
        waterFall('main','box');

        //滾動加載盒子
        window.onscroll = function (){
            //判斷是否加載
            if (checkWillLoad())
            {
                //創造假數據
                var data = {'dataImg':[{'img':'22.jpg'},{'img':'22.jpg'},{'img':'22.jpg'},{'img':'22.jpg'},{'img':'22.jpg'},{'img':'22.jpg'}]};
                //加載數據
                for(var i=0; i<data.dataImg.length; i++)
                {
                    //創建最外面的盒子
                    var newBox = document.createElement('div');
                    newBox.className = 'box';
                    $('main').appendChild(newBox);
                    //創建單個盒子
                    var newPic = document.createElement('div');
                    newPic.className = 'pic';
                    newBox.appendChild(newPic);
                    //創建img
                    var newImg = document.createElement('img');
                    newImg.src = 'images/' + data.dataImg[i].img;
                    newPic.appendChild(newImg);
                }
                //把剛創建的盒子瀑布流佈局
                waterFall('main','box');
            }
        }
    }

    //實現瀑布流佈局
    //規則:從第二行開始的圖片,總是拼接在上一行高度最矮的圖片後面
    function  waterFall(parent,box) {
        //父盒子居中
        //通過父盒子拿到所有的子盒子
        var allBox = $(parent).getElementsByClassName(box);
        //求出盒子的寬度
        var boxWidth = allBox[0].offsetWidth;
        //求出瀏覽器的寬度(包括邊框的寬高)
        var screenWidtn = document.body.offsetWidth;
        //求出列數 //取整函數取整
        var cols = Math.floor( screenWidtn/boxWidth);
        //父標籤居中
        //先求出父標籤寬度
        $(parent).style.width = boxWidth * cols + 'px';
        //居中
        $(parent).style.margin = '0 auto';

        //子盒子定位
        //創建一個高度數組,存所有的高度
        var heightArr = [];
        //遍歷
        for(var i = 0; i < allBox.length ;i++)
        {
            //求出每個盒子的高度
            var boxHeight = allBox[i].offsetHeight;
            //第一行的盒子不需要重新定位//每一行的盒子數與列數相同
            if(i<cols)
            {
                //添加第一行所有盒子高度
                heightArr.push(boxHeight);
            }
            else//剩下的盒子都需要瀑布流佈局
            {
                //求出最矮的盒子高度
                var minBoxHeight = Math.min.apply(this,heightArr);
                //求出最矮盒子對應的索引
                var minBoxIndex = getMinBoxIndex(minBoxHeight,heightArr);
                //盒子瀑布流定位  頂部間距就是最矮盒子的高度
                allBox[i].style.position = 'absolute';
                allBox[i].style.top = minBoxHeight + 'px';
                allBox[i].style.left = minBoxIndex * boxWidth +'px';
                //關鍵:更新數組最矮高度,使下一個圖片在高度數組中總是找最矮高度的圖片下面拼接
                heightArr[minBoxIndex] += boxHeight;
            }
        }
    }

    //求出最矮盒子對應的索引函數
    function getMinBoxIndex(val,arr) {
        for(var i in arr)
        {
            if(val == arr[i])
            {
                return i;
            }
        }
    }

    //加載更多規則:當瀏覽器最下方到達圖片的高度一半時讓其刷新出來
    //判斷是否符合加載條件
    function checkWillLoad() {
        //取出所有盒子
        var allBox = $('main').getElementsByClassName('box');
        //取出最後一個盒子
        var lastBox = allBox[allBox.length - 1];
        //求出最後一個盒子高度的一半 + 內容與瀏覽器頭部的偏離位置
        var lastBoxDis = lastBox.offsetHeight * 0.5 + lastBox.offsetTop;
        //求出瀏覽器的高度
        // 注意:JS代碼存在瀏覽器兼容問題 一般分標準模式(按屏幕算document.body.offsetHeight)和混雜模式(按所有內容算)
        var screenHeight =  document.documentElement.clientHeight;
        //頁面偏離屏幕的高度
        var scrollTopHeight = document.body.scrollTop;
        //判斷
        return lastBoxDis <= screenHeight + scrollTopHeight;
    }
</script>

</body>
</html>

這裏寫圖片描述

.3 Third way is same to second but use jq to write

// document.write("<script src='jquery-3.1.1.min.js'></script>");
//當頁面加載完畢
$(window).on('load',function () {
    //1.實現瀑布流佈局
    waterFall();

    //2.滾動加載
    $(window).on('scroll',function () {
        //判斷是否加載
        if (checkWillLoad())
        {
            ////創造假數據
            var data = {'dataImg':[{'img':'23.jpg'},{'img':'24.jpg'},{'img':'25.jpg'},{'img':'26.jpg'},{'img':'27.jpg'},{'img':'28.jpg'}]};
            //遍歷創建盒子
            $.each(data.dataImg,function (index,value)
                   {
                       //創建一個div標籤 設置它的類爲'box' 添加到'main'裏面去
                       var newBox = $('<div>').addClass('box').appendTo($('#main'));
                       var newPic = $('<div>').addClass('pic').appendTo($(newBox));
                       //創建img  取出遍歷的對象value的img屬性對應的值
                       $('<img>').attr('src','images/'+$(value).attr('img')).appendTo($(newPic));
                   })
            //1.實現瀑布流佈局
            waterFall();
        }
    });
});

//實現瀑布流佈局
function waterFall () {
    //拿到所有的盒子
    var allBox = $('#main > .box');
    //取出其中一個盒子的寬度
    var boxWidth = $(allBox).eq(0).outerWidth();
    //取出屏幕的高度
    var screenWidth = $(window).width();
    //求出列數 //取整函數取整
    var cols = Math.floor( screenWidth/boxWidth);
    //父標籤居中
    $('#main').css({
        'width':cols * boxWidth + 'px',
        'margin':'0 auto'
    });
    //對子盒子定位
    var heightArr = [];
    //遍歷
    $.each(allBox,function (index,value) {
        //取出單獨盒子的高度
        var boxHeight = $(value).outerHeight();
        //判斷是否第一行
        if(index < cols)
        {
            heightArr[index] = boxHeight;
        }
        else  //剩餘的盒子要瀑布流佈局
        {
            //求出最矮的盒子高度
            var minBoxHeight = Math.min.apply(null,heightArr);
            //取出最矮高度對應的索引  封裝了js的這個方法
            var minBoxIndex = $.inArray(minBoxHeight,heightArr);
            //定位
            $(value).css({
                'position':'absolute',
                'top':minBoxHeight + 'px',
                'left':minBoxIndex * boxWidth + 'px'
            });
            //更新數組中最矮的高度
            heightArr[minBoxIndex] += boxHeight;
        }
    })

}

//判斷是否符合加載條件
function checkWillLoad() {
    //直接取出最後一個盒子
    var lastBox = $('#main > div').last();
    //取出最後一個盒子高度的一半 + 頭部偏離的位置
    var lastBoxDis = $(lastBox).outerHeight() + $(lastBox).offset().top;
    //求出瀏覽器的高度
    var clientHeight = $(window).height();
    //求出頁面偏離瀏覽器高度
    var scrollTopHeight = $(window).scrollTop();
    //比較返回
    return lastBoxDis <= clientHeight + scrollTopHeight;

}
The effect is same to above.

refer:http://www.jianshu.com/p/0a9b27e7da36

        thanks for reading
發佈了283 篇原創文章 · 獲贊 242 · 訪問量 38萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章