轉眼間3個月沒有更新了…..最近莫名的迷戀上了前端各種效果的實現了…..最近就記錄一下我這幾天做畢設時使用的一些效果吧~
今天記錄的是我畢設中着重體現的布局風格--瀑布流布局。
說到瀑布流布局,先上張圖片來說明一下什么是瀑布流好了。
這個是我畢設中的一個截圖(內容是我暫時從其他網站上爬下來測試的….),那么我們從這張圖片中就能看到大致來說瀑布流就是一些等寬不等高的圖片來排列展示的,因為每張圖片都不一樣大,以及我在圖片下面展示了各種信息都不一樣,所以導致這些展示的框它們的高度都不統一,那么為什么卻要要求它們之間的寬度相同呢?這就是瀑布流實現的關鍵了。
那么我們就來一步步的說明它是如何實現的,這個過程中也就理解了為什么是這樣設計的了,首先,我們要在頁面中排列出所要展示的框的個數,下面是這個瀑布流的結構圖:
這張圖片中白色的部分我們就當作是瀏覽器的可視區域了,那么中間這個灰色的部分我給他取名叫做‘main’,用來存放中間展示的圖片,並且與頁面中的其他元素分開,那么第一個問題就來了,我們如何知道在這個main中到底改放幾張圖片呢?而且這個main的寬度又該怎么定呢?上代碼!
#main{ position: relative; text-align: center; margin: 0 auto; }
我們先給它設置一下相對定位,並將這個div設置成居中,這里有個地方要注意的是,之前看了很多例子使用 text-align: center 將div居中后發現並不起效,那是因為在設置text-align的同時並沒有指定它的margin值,我們要將margin值也同時設置了之后居中的效果才會生效,因為要和頁面頂部的導航欄配合,所以我在這里將margin的第一個值設置為0,第二個設置為自動(auto),為什么這么設置呢?
margin 簡寫屬性在一個聲明中設置所有外邊距屬性。該屬性可以有 1 到 4 個值。這個簡寫屬性設置一個元素所有外邊距的寬度,或者設置各邊上外邊距的寬度。在這里要注意一下的是在css中,margin和padding這樣的屬性設置值的時候都是順時針設置的,也就是上,右,下,左,這個順序來的。
那么當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; }
現在整個瀑布流的展示就完成了,今天在這里記錄下來,留已備用。