前端頁面--瀑布流佈局的實現

      轉眼間3個月沒有更新了…..最近莫名的迷戀上了前端各類效果的實現了…..最近就記錄一下我這幾天作畢設時使用的一些效果吧~css

      今天記錄的是我畢設中着重體現的佈局風格--瀑布流佈局。前端

      說到瀑布流佈局,先上張圖片來講明一下什麼是瀑布流好了。jquery

QQ截圖20150315171940

      這個是我畢設中的一個截圖(內容是我暫時從其餘網站上爬下來測試的….),那麼咱們從這張圖片中就能看到大體來講瀑布流就是一些等寬不等高的圖片來排列展現的,由於每張圖片都不同大,以及我在圖片下面展現了各類信息都不同,因此致使這些展現的框它們的高度都不統一,那麼爲何卻要要求它們之間的寬度相同呢?這就是瀑布流實現的關鍵了。json

      那麼咱們就來一步步的說明它是如何實現的,這個過程當中也就理解了爲何是這樣設計的了,首先,咱們要在頁面中排列出所要展現的框的個數,下面是這個瀑布流的結構圖:數組

QQ截圖20150315173751

      這張圖片中白色的部分咱們就看成是瀏覽器的可視區域了,那麼中間這個灰色的部分我給他取名叫作‘main’,用來存放中間展現的圖片,而且與頁面中的其餘元素分開,那麼第一個問題就來了,咱們如何知道在這個main中到底改放幾張圖片呢?並且這個main的寬度又該怎麼定呢?上代碼!瀏覽器

#main{
    position: relative; text-align: center; margin: 0 auto;
}

     咱們先給它設置一下相對定位,並將這個div設置成居中,這裏有個地方要注意的是,以前看了不少例子使用 text-align: center 將div居中後發現並不起效,那是由於在設置text-align的同時並無指定它的margin值,咱們要將margin值也同時設置了以後居中的效果纔會生效,由於要和頁面頂部的導航欄配合,因此我在這裏將margin的第一個值設置爲0,第二個設置爲自動(auto),爲何這麼設置呢?app

     margin 簡寫屬性在一個聲明中設置全部外邊距屬性。該屬性能夠有 1 到 4 個值。這個簡寫屬性設置一個元素全部外邊距的寬度,或者設置各邊上外邊距的寬度。在這裏要注意一下的是在css中,margin和padding這樣的屬性設置值的時候都是順時針設置的,也就是上,右,下,左,這個順序來的。ide

      那麼當margin的值爲四個的時候這4個的值依次爲:上外邊距,右外邊距,下外邊距,左外邊距。函數

      當爲三個值的時候順序依次爲:上外邊距,左右外邊距,下外邊距。佈局

      當爲兩個值的時候順序依次爲:上下外邊距,左右外邊距。

      當爲一個值的時候就是所有的外邊距了。

      如今咱們就要開始放圖片了,這也就是爲何咱們要使用等寬的圖片了,由於寬度固定咱們才能動態的算出不一樣大小的瀏覽器能放幾張圖片來展現了。

     這裏我並無先設置main的寬度,而是在計算出放置幾張圖片以後才設置它的寬度,由於咱們不只僅是展現圖片,還有圖片下面的內容,因此在計算每張圖片的寬度的時候要將包裹圖片的容器也算進來,也就是上面圖片中紅色框的寬度,並且因爲每一個展現框之間還有margin值,因此咱們在計算的時候也是要考慮的,由於我使用的是jquery,因此在這裏我經過 outerWidth() 方法來取得寬度值。

//動態添加瀑布圖片的功能函數
function waterfall(){

    //取得展現框對象
    var $boxs = $( "#main>div" );

    // 一個塊框的寬
    var w = $boxs.eq( 0).outerWidth();

    //每行中能容納的展現框個數【窗口寬度除以一個塊框寬度】
    var cols = Math.floor( ($( window ).width()-30) / w );

    //給最外圍的main元素設置寬度和外邊距
    $('#main').width(w*cols).css('margin','o auto');

    //用於存儲 每列中的全部塊框相加的高度。
    var hArr=[];

    $boxs.each( function( index, value ){
        var h = $boxs.eq( index).outerHeight();
        if( index < cols ){
            hArr[ index ] = h; //第一行中的num個塊框 先添加進數組HArr
        }else{
            var minH = Math.min.apply( null, hArr );//數組HArr中的最小值minH
            var minHIndex = $.inArray( minH, hArr );
            $( value).css({
                'position':'absolute','top':minH+'px', 'left':minHIndex*w + 'px'
            });
            //數組 最小高元素的高 + 添加上的展現框[i]塊框高
            hArr[ minHIndex ] += $boxs.eq( index).outerHeight();//更新添加了塊框後的列高
        }
    });
}

     這裏的思路就是先取得瀏覽器的可視寬度,而後經過除以每一個展現框的寬度來計算出一排能夠展現多少個展現框的,而後經過一個數組 hArr來保持每一列的高度,我在這裏使用jquery中的each方法來循環保存每一列的高度,這裏傳入的兩個參數,index是展現框的索引號,value爲這個展現框的jquery對象。

     首先根據索引號來取到對應展現框的高度,這個高度是包含了margin的所有寬度,而後將這個值保存在數組中,因爲以前求出了每一行最多的塊數,因此在這裏進行一個判斷,將第一行首先填滿,而後開始填充第二排的展現框,我使用Math.min.apply()方法來取得數組中的最小值,而後經過jquery提供的 inArray() 方法來取得最小值所在的是哪一列,第一個參數是最小值,第二個參數是須要判斷的數組,而後咱們將對應的展現框填充進去,最後將新加入的展現框的完整高度加上以前最小的高度從新保存到數組中,繼續循環判斷,從而不斷的新增展現框。

      那麼如今咱們就要經過後臺傳來的json數據動態的生成新的展現框來提供添加了,由於每一個項目所要展現的內容都不同,我在這裏就不展現具體的代碼 了,接下來就是要經過監聽滾動條的滑動來判斷何時開始動態添加新展現框了。

      接下來我就講一下我判斷的思路,首先是在第一組展現框添加完成後取得最後一個展現框的填充高度,而後加上這個展現框自身高度的一邊,由於我以爲用戶通常會瀏覽到最後一個的附近的時候就該開始動態填充了,因此我在這裏就判斷當前滾動條滾動的距離是否是大於頁面默認的高度加上最後一個展現框到屏幕頂端的高度,若是大於了說明就該繼續填充展現框了:

//監聽滾動條
    window.onscroll=function(){
        if(checkscrollside()){
            AddWaterfall
(dataInt);//這個是動態填充新展現框的函數
            waterfall();
        };
    }

//判斷是否須要繼續加載瀑布流
function checkscrollside(){
    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;
}

       如今整個瀑布流的展現就完成了,今天在這裏記錄下來,留已備用。

相關文章
相關標籤/搜索