前言
like a mountain that is in our path,wo cannot complain that it is there,we simply have to climb it
起由
最近,在搭建個人博客時,其中的Demo展示頁面想用瀑布流形式展現,發現現有的js插件大多基於JQ的,而我稍微有點小強迫,不想基於JQ,於是就着手自己封裝了一個。順帶就研究了下css3方式實現瀑布流,於是總結了下,寫了幾個示例demo,就有了本文。
幾種常用的瀑布流介紹
一般瀑布流的實現常見有三種方式
- 傳統的多列浮動
- css3樣式定義
- js計算絕對布局
傳統的多列浮動簡介
首先固定屏幕中展示的列數,每一列中間的數據作為一組單獨計算,插入數據時分別插入不同列中
優點:
- 布局最為簡單,一般只依賴與一個浮動布局
- 不需要知道內容的高度,所以當有圖片未加載時也不影響
缺點:
- 只適用於特定的屏幕,當屏幕size變化時,無法動態實現列數的更改
- 拓展不易
css3樣式定義瀑布流簡介
利用css3中特有屬性,在高級瀏覽器中實現瀑布流效果
優點:
- 直接使用css樣式,最為簡潔,不依賴於任何js
- 拓展方便,直接往容器內部添加內容即可
- 自適應,屏幕變化,布局也會變化
- 當各個item的寬度不一致時,這種方式也適用
- 像一些特殊的如固定的兩列瀑布流也可以很方便實現(固定顯示兩列,每一列可以橫着有多個item)
缺點:
- 需要高級瀏覽器支持(其實這個現在已經不算缺點了)
- 這種方式和普通瀑布流的原理有區別,不是分別往不同列中插入數據,而是先往一列中插入數據,達到一定高度后再往其它列中插入數據,有時候用這種方式會達不到預期效果(這個是比較關鍵的,這種方式有時候體驗達不到預期)
js計算絕對布局實現瀑布流簡介
利用js,動態計算元素的插入位置,利用絕對布局absolute進行定位,根據屏幕的不同可以動態調整
優點:
- 便於拓展,方便數據的添加
- 自適應,屏幕變化,布局也會變化
缺點:
- 計算時需要知道內容高度,如果包含圖片,需要等圖片加載完畢再計算,否則會存在誤差
- 各個item的寬度需要一致
就實用性而言,傳統的瀑布流比較適合業務場景較為單一的情況,比如手機中固定兩列的情況,css3瀑布流布局由於有時候會造成一些不理想的局面,所以更多的被用在了面試題等上面,最后那張絕對布局的瀑布流方式是被應用的最為廣泛的
本文主要探討css3瀑布流和絕對定位瀑布流的實現
css3瀑布流的實現
這種實現方式是最為簡單的,僅僅是基於css3的新屬性(column-width或column-count),
css3中增加了一個新的屬性:column,來實現等高的列的布局效果。該屬性有column-width寬度,column-count數量等,並且能根據窗口自適應。
css實現瀑布流分為兩種效果,普通橫向瀑布流與固定列數的瀑布流
普通橫向瀑布流
這種瀑布流方式常常用於和js絕對布局方式比較,但是雖然從顯示上來說,效果差不多,但是從用戶體驗的角度講,這個不符合平常的習慣,以下是兩種方式的效果圖對比
實現代碼
.container{
/*寬*/
-webkit-column-width:200px;
-moz-column-width:200px;
-o-colum-width:200px;
/*間距*/
-webkit-column-gap:1px;
-moz-column-gap:1px;
-o-column-gap:1px;
}
固定列數的瀑布流
這種布局用到比較少,但是某些面試題會經常提到,效果如下
實現代碼
.container{
/*固定列*/
/*-moz-column-count:2;
-webkit-column-count:2;
column-count:2;*/
/*間距*/
-webkit-column-gap:1px;
-moz-column-gap:1px;
-o-column-gap:1px;
}
示例與源碼
想看示例頁面可以戳一戳
css3瀑布流效果
源碼可以查看
https://github.com/dailc/showDemo/blob/master/waterfallflow/demo_waterfall_flow_css3.html
js絕對布局瀑布流實現
這種實現方式是最為經典的,也是運營的最多的,網上也有很多的原生或jq插件,本文這里也用原生js重新封裝了一個類庫,方便調用,效果如圖
實現思路
瀑布流的實現思路其實很簡單,如下:
- 獲取元素容器的總寬度allWith, 每一個瀑布流元素的列寬度 itemWidth(如果大於allwidth,會有一個默認值替代)
- 計算當前容器可以顯示的列數 column Math.floor(allwidth/itemWidth) 向下取整
- 添加一個元素前,計算每一列當前的高度,尋找當前高度最小的列,然后根據列的序號k,確定item的left和top,lef=k*itemWidth top=當前列的高度,然后當前列插入這個元素,當前列的高度加上這個元素的高度
- 所有元素插入完畢后,容器的高度會調整為最大列的高度
- 初始化就是先讀取頁面的所有元素,然后一個一個插入,加載更多就是在已有的元素基礎上,插入新的元素計算
實現代碼
由於代碼較為占用篇幅,這里就不再贅述,基本根據實現思路都能實現出來,也可以查看下面提供的源碼鏈接
示例與源碼
想看示例頁面可以戳一戳
js瀑布流效果
源碼可以查看
https://github.com/dailc/showDemo/blob/master/waterfallflow/demo_waterfall_flow_js.html
原文地址
原文在我個人博客上面