新聞中心
瀑布流布局是一種比較流行的頁面布局方式,表現(xiàn)為參差不齊的多欄卡片。跟網(wǎng)格布局相比,顯得更靈動,更具藝術氣息。

創(chuàng)新互聯(lián)公司從2013年開始,是專業(yè)互聯(lián)網(wǎng)技術服務公司,擁有項目成都網(wǎng)站設計、成都做網(wǎng)站網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元如東做網(wǎng)站,已為上家服務,為如東各地企業(yè)和個人服務,聯(lián)系電話:13518219792
瀑布流布局
實現(xiàn)瀑布流布局的方式有多種,比如multi-column布局,grid布局,flex 布局等。但是這些實現(xiàn)方式都有各自的局限性,代碼也略復雜。
其實,有個最原始、最簡單,也是兼容性最好的實現(xiàn)方式,那就是使用絕對定位。瀑布流布局的元素是一些等寬不等高的卡片,只要根據(jù)元素的實際寬高計算出自己的坐標位置就行了。
要計算坐標自然要用到 JavaScript,這就不是純 CSS 方案,對某些前端極客來講顯得不那么純粹。不過只要理清思路了,也用不了幾行代碼。本文就給出最近實現(xiàn)的一個版本。
- // 計算每個卡片的坐標
- export function calcPositions({ columns = 2, gap = 7, elements }) {
- if (!elements || !elements.length) {
- return [];
- }
- const y = []; //上一行卡片的底部縱坐標數(shù)組,用于找到新卡片填充位置
- const positions = []; // 每個卡片的坐標數(shù)組
- elements.forEach((item, index) => {
- if (y.length < columns) { // 還未填滿一行
- y.push(item.offsetHeight);
- positions.push({
- left: (index % columns) * (item.offsetWidth + gap),
- top: 0
- });
- } else {
- const min = Math.min(...y); // 最小縱坐標
- const idx = y.indexOf(min); // 縱坐標最小的卡片索引
- y.splice(idx, 1, min + gap + item.offsetHeight); // 替換成新卡片的縱坐標
- positions.push({
- left: idx * (item.offsetWidth + gap),
- top: min + gap
- });
- }
- });
- // 由于采用絕對定位,容器是無法自動撐開的。因此需要計算實際高度,即最后一個卡片的top加上自身高度
- return { positions, containerHeight: positions[positions.length - 1].top + elements[elements.length - 1].offsetHeight };
- }
上面這段代碼的作用就是計算每個卡片的left、top,以及容器的總高度。關鍵位置都有注釋,應該不難理解。
有了這幾行核心代碼,要想封裝成瀑布流組件就很容易了。以 Vue 為例,可以這樣封裝:
MasonryLite.vue
使用組件:
![]()
{{ item.title }}
不過這樣其實還會有點問題,就是doLayout的執(zhí)行時機。因為該方案基于絕對定位,需要元素在渲染完成后才能獲取到實際寬高。如果卡片內(nèi)有延遲加載的圖片或者其他動態(tài)內(nèi)容,高度會發(fā)生變化。這種情況下就需要在DOM更新后主動調(diào)用一次doLayout重新計算布局。
如果大家有更好的實現(xiàn)方案,歡迎交流!
代碼倉庫:https://github.com/kaysonli/masonry-lite
npm 包:masonry-lite
如果覺得對你有幫助,幫忙點個不要錢的star。
本文轉(zhuǎn)載自微信公眾號「1024譯站」,可以通過以下二維碼關注。轉(zhuǎn)載本文請聯(lián)系1024譯站公眾號。
新聞名稱:實現(xiàn)瀑布流布局,就這幾行代碼?
標題網(wǎng)址:http://m.fisionsoft.com.cn/article/cogdcpc.html


咨詢
建站咨詢
