瀑布流佈局

瀑布流佈局

瀑布流,又稱瀑布流式佈局。

是比較流行的一種網站頁面佈局,視覺表現爲參差不齊的多欄佈局,隨着頁面滾動條向下滾動,這種佈局還會不斷加載數據塊並附加至當前尾部。

瀑布流特點:等寬不等高,第二行的第一張圖片要加載到第一行中最矮的圖片的下面。

1. 原生JavaScript方式實現

index.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>waterfall_flow_layout</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        #main{
            position: relative;
        }
        .box{
            padding: 15px 0 0 15px;     /*設置頂部和底部的距離*/
            float: left;                /*設置圖片浮動(顯示在同一行)*/
        }
        .pic{
            padding: 10px;              /*內邊距*/
            border:1px solid #ccc;      /*邊框*/
            border-radius: 5px;         /*圓角*/
            box-shadow: 0 0 5px #ccc;   /*設置陰影,水平和垂直陰影都爲0,陰影程度爲5px*/
        }
        .pic img{
            width:165px;                /*設置圖片都等寬*/
            height: auto;
        }
    </style>
</head>

<body>
    <div id="main">
        <div class="box">
            <div class="pic">
                <img src="./images/0.jpg">              
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/1.jpg">              
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/2.jpg">              
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/3.jpg">              
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/4.jpg">              
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/5.jpg">              
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/6.jpg">              
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/7.jpg">              
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/8.jpg">              
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/9.jpg">              
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/10.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/11.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/12.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/13.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/14.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/15.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/16.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/17.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/18.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/19.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/20.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/21.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/22.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/23.jpg">             
            </div>
        </div>
    </div>
    <script src="./js/js_waterfall_flow_layout.js"></script>
</body>
</html>

js_waterfall_flow_layout.js

//原生JavaScript實現瀑布流佈局

window.οnlοad= function(){
    waterfall('main','box');
    //模擬從後臺來的數據
    var dataInt = {"data":[{"src":'24.jpg'},{"src":'25.jpg'},{"src":'26.jpg'},{"src":'27.jpg'}]};
    window.onscroll = function(){
        if(checkScrollSlide){
            var oParent = document.getElementById('main');
            //將加載的數據渲染到當前頁面的尾部
            for(var i=0; i <dataInt.data.length; i++){
                var oBox = document.createElement('div'); //添加 元素節點
                oBox.className = 'box';    //添加 類名 name屬性
                oParent.appendChild(oBox); //添加子元素到父元素的後面
                oPic = document.createElement('div');
                oPic.className = 'pic';
                oBox.appendChild(oPic);
                var oImg = document.createElement('img');
                oImg.src = './images/' + dataInt.data[i].src;
                oPic.appendChild(oImg);
            }
            waterfall('main','box');  //再次調用瀑布流佈局
        }
    }
}

//瀑布流佈局實現
function waterfall(parent, box){
    //將main下的所有class爲box的元素取出來
    var oParent = document.getElementById(parent);
    //獲取parent父元素下的所有box元素
    var oBoxes = getByClass(oParent, box);
    //計算整個頁面的列數( 頁面寬 / box的寬 )
    //offsetWidth:獲取元素的寬度(width + padding + border + 父級padding)
    var oBoxW = oBoxes[0].offsetWidth;
    var cols = Math.floor(document.documentElement.clientWidth / oBoxW); //獲取頁面寬度除以box的寬
    oParent.style.cssText = 'width:' + oBoxW*cols + 'px;margin:0 auto;'; //設置main的寬度,設置之後居中
    var hArr = []; //數組中先存的是第一行的6張圖片的高度,之後存的是每一列的圖片的高度
    for(var i=0; i<oBoxes.length; i++){
        if(i < cols){
            hArr.push(oBoxes[i].offsetHeight);
        }else{
            var minH = Math.min.apply(null,hArr);  //apply()改變函數(方中)this的指向
            var oIndex = getMinhIndex(hArr, minH); //數組中值最小的索引
            //改變盒子的位置
            oBoxes[i].style.position = 'absolute';
            oBoxes[i].style.top = minH + 'px';
            //oBoxes[i].style.left = oBoxW * oIndex + 'px';
            oBoxes[i].style.left =  oBoxes[oIndex].offsetLeft + 'px'; //另一種方法
            //改變最小值 : 原來的值 + 新加的圖片的值
            hArr[oIndex] += oBoxes[i].offsetHeight;
        }
    }
}

//根據class獲取元素(獲取指定父元素下的所有子元素)
function getByClass(parent, className){
    var boxArr = [];  //用來存儲取到的所有class爲box元素
    var oElements = parent.getElementsByTagName('*');
    //遍歷所有獲取到的元素
    for(var i = 0; i<oElements.length; i++){
        if(oElements[i].className == className){
            boxArr.push(oElements[i]);
        }
    }
    return boxArr;
} 

//找出數組中的最小值的索引
function getMinhIndex(arr,val){
    for(var i in arr){
        if(arr[i] == val){
            return i;
        }
    }
}

//檢查是否具備滾動加載數據塊的條件 (以最後一個數據塊的距離爲判斷條件)
function checkScrollSlide(){
    var oParent = document.getElementById('main');
    var oBoxs = getByClass(oParent,'box'); //找出最後一個元素盒子
    //找出最後一個元素盒子距離頂部的高度
    var lastBoxH = oBoxs[oBoxs.length - 1].offsetTop + Math.floor(oBoxs[oBoxs.length-1].offsetHeight / 2);
    //滾動條向下滾動的距離(上面看不見的)
    var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
    //當前瀏覽器頁面的可視高度
    var height = document.body.clientHeight || document.documentElement.clientHeight;
    return (lastBoxH > scrollTop + height) ? true : false;
}

2. 用jQuery實現

引入jQuery: <script src="./js/jquery-1.8.3.min.js"></script>

然後只需要將上面的引入的js代碼改成如下即可:

//用jQuery實現瀑布流佈局
$(window).on('load', function(){
    waterfall();
    var dataInt = {"data":[{"src":'24.jpg'},{"src":'25.jpg'},{"src":'26.jpg'},{"src":'27.jpg'}]};
    //滾動條事件
    $(window).on('scroll', function(){
        if(checkScrollSlide){
            $.each(dataInt.data, function(key,value){
                //利用jquery的兩大特點:支持連綴,隱式迭代
                var oBox = $('<div>').addClass('box').appendTo($('#main'));
                var oPic = $('<div>').addClass('pic').appendTo($(oBox));                
                var oImg = $('<img>').attr('src','./images/' + $(value).attr('src')).appendTo($(oPic));
            });
        }
        waterfall();
    })
});

//實現瀑布流佈局(不能滾動)
function waterfall(){
    var $boxs = $('#main>div'); //獲取class爲box的元素
    var w = $boxs.eq(0).outerWidth(); //outerWidth獲取的寬度值包含padding border
    var cols =Math.floor($(window).width() / w ); //計算列數
    $('#main').width(w*cols).css('margin','0 auto');
    var hArr = [];
    $boxs.each(function(index,value){
        //index 索引 value是一個dom對象
        var h = $boxs.eq(index).outerHeight();
        if(index < cols){  //前cols個圖片
            hArr[index] = h;
        }else{
            var minH = Math.min.apply(null,hArr);
            var minHIndex = $.inArray(minH,hArr);
            //設置從第七張之後的圖片的位置
            $(value).css({ //將dom對象轉換成jquery對象
                'position':'absolute',
                'top':minH  + 'px',
                'left': minHIndex*w + 'px'
            });
            hArr[minHIndex] += $boxs.eq(index).outerHeight();
        }
    });
}

//判斷是否具備滾動的條件
function checkScrollSlide(){
    //獲取最後一個元素
    var $lastBox = $('#main>div').last();
    var lastBoxDis = $lastBox.offset().top + Math.floor($lastBox.outerHeight() / 2);
    //獲取頁面滾走的距離
    var scrollTop = $(window).scrollTop();
    //獲取可視頁面的高度
    var documentH = $(window).height();
    return (lastBoxDis < scrollTop + documentH) ? true : false;
}

3. 用css3實現(主要用到多欄佈局的新特性)

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>css3_waterfall_flow_layout</title>
    <style>
        #main{
            /* 設置列寬,202 = 圖片寬度165 + 內邊距10*2 + 邊框1*2 + box的15 */
            -webkit-column-width: 202px;  
            -moz-column-width: 202px;
            -o-column-width:202px;
            -ms-column-width:202px;
        }
        .box{
            padding: 10px 0 0 15px;
        }
        .pic{
            padding:10px;
            border:1px solid #ccc;
            border-radius: 5px;
            box-shadow:0 0 5px #ccc; 
            width:165px;
        }
        .pic img{
            display: block;
            width:165px;
            height: auto;
        }
    </style>
</head>

<body>
    <div id="main">
        <div class="box">
            <div class="pic">
                <img src="./images/0.jpg">              
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/1.jpg">              
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/2.jpg">              
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/3.jpg">              
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/4.jpg">              
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/5.jpg">              
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/6.jpg">              
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/7.jpg">              
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/8.jpg">              
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/9.jpg">              
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/10.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/11.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/12.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/13.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/14.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/15.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/16.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/17.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/18.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/19.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/20.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/21.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/22.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/23.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/24.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/25.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/26.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/27.jpg">             
            </div>
        </div>
        <div class="box">
            <div class="pic">
                <img src="./images/28.jpg">             
            </div>
        </div>
    </div>
</body>
</html>

4. 對比瀑布流佈局實現方式:

原生JS:

  1. 需要計算, 列數 = 瀏覽器窗口寬度 / 圖片寬度 ,圖片定位是根據每一列數據庫的高度計算接下來圖片的位置。

  2. 圖片順序是按照圖片計算的位置橫向排列,位置是計算出來的,比較規範。

css3:

  1. 不需要計算,瀏覽器自動計算,只需要設置列寬,性能高

  2. 列寬隨着瀏覽器窗口大小進行改變,用戶體驗不好

  3. 圖片排序按照垂直順序排列,打亂圖片顯示順序

  4. 圖片加載還是依靠JavaScript實現

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章