談談實現瀑布流布局的幾種思路

2022-01-13 23:26:29 字數 1460 閱讀 3736

最近遇到這麼乙個需求,需要在手機上做乙個兩列的瀑布流布局,後來就把這個問題研究了一下,做個記錄。

一般來講,這種布局可以分為兩種情況:

的數量是一定的,不需要頁面滾動到底部時,再動態載入,只需要將排成若干列

的數量的不定的,頁面觸底時,需要從遠端載入。

前者使用css的方法即可解決,後者則需要js來幫忙。

一、css多列布局

.photos
得到的效果如下:

see the pen kjmjmq by imgss

(@imgss) on codepen.

二、flex布局

flex布局同樣可以做到這一點,訣竅在於將flex-direction設為column;但是相對於多列布局,需要根據瀑布流的列數,計算乙個合適的容器高度,不然可能會導致多出一行。如果你在下面的demo 中,看到了4列,不要懷疑,就是我計算的容器高度不合適導致的。。。

see the pen waterflow-flex by imgss

(@imgss) on codepen.

當需要動態插入時,上面的兩種方法就不合適了,因為他們本質上是將按照縱向進行排列的。動態插入時通常我們希望是按橫向插入到容器中的。這時候就需要js來幫忙了。首先,我們看看瀑布流和揹包問題的關係。

瀑布流的基本思路是將一堆放到若干列中,列與列之間的高度比較均勻,而不會相差太大。假如我們要分成兩列,那麼,問題就變成了,從 n 張中挑出 m 張,使這 m 張的總高度盡量接近 n 張總高度的 1 / 2。於是這就變成了乙個揹包問題

01揹包問題

揹包問題是啥這裡不做展開,說白了是將乙個複雜的問題分解為幾個簡單的問題,大佬們講的都比我好,網上也有各個語言版本的實現,不太了解的同學可以檢視上面的鏈結。這裡直接放乙個函式

function dp(ws, vs, limit)  else }}

// 回溯得到應該選哪些

let max = limit;

let selected = ;

for (let idx = len - 1; idx >= 0; idx--) }}

return selected;

}

有了這個解法之後,我們也就不難寫出乙個瀑布流布局。具體思路是:假設我們要做乙個3列的瀑布流布局,那麼可以不斷從陣列中選出一組,使的高度接近總高度的1/3,最終得到3組。下面是乙個**片段

// colcount 表示要生成幾列

while(colcount--)

})}

下面這個demo就是按上面的思路實現的,可以拖動下面的滑塊來改變列數,觀察底部的間隙。在使用揹包演算法解決瀑布流問題時,乙個需要我們注意的地方是,要將高度轉化成整數。

see the pen waterflow-js by imgss

(@imgss) on codepen.

參考文章:

實現瀑布流布局

瀑布流,又稱瀑布流式布局。是比較流行的一種 頁面布局,視覺表現為參差不齊的多欄布局,隨著頁面滾動條向下滾動,這種布局還會不斷載入資料塊並附加至當前尾部,瀑布流的主要特性便是錯落有致,定寬而不定高的設計讓頁面區別於傳統的矩陣式布局模式。主體思路是記錄每一列的高度,父容器相對定位,成員絕對定位,利用to...

JavaScript實現瀑布流布局

在一些購物類 上會看到一種諸如下圖的類似瀑布流布局,這種布局的乙個特點是每乙個盒子的寬度相同,而高度卻是任意的。div 通過乙個div.pic box盒子來控制每個元素之間的間隔,div.pic來給元素新增邊框效果。由於後面div.pic box需要絕對定位,所以給它的父元素乙個position r...

js實現瀑布流布局

1.瀑布流的布局,要求布局的元素是等寬的,瀑布流布局的特點就是等寬不等高,然後計算元素的寬度和瀏覽器螢幕寬度的比值,確定出列數 2.建立乙個陣列,這個陣列用於儲存第一行的各個高度 3.計算出這個陣列中最小的元素,接下來的通過定位的方式布局到高度最小的下面,4.最後將這個最小高度進行更新,然後一直迴圈...