瀑布流的實現(xiàn)

瀑布流即參差不齊的多欄布局,可向下滾動,且隨著向下滑動不斷加載新的內容

image.png

以下是一些實現(xiàn)方式,只提供用于兩欄布局瀑布流的簡單思路,多欄瀑布流按照思路也可很快實現(xiàn),自己去想,懶得寫了

js實現(xiàn)

利用js計算和填充數(shù)據(jù)

直接上代碼

<view class="content">
  <view class="content-left">
    <view class="item" v-for="item in listLeft" :key="item.index">{{ item.content}}</view>
  </view>
  <view class="content-right">
    <view class="item" v-for="item in listRight" :key="item.index">{{ item.content }}</view>
  </view>
  <view class="noShow">
    <view ref="list" class="item" v-for="item in list" :key="item.index">{{ item.content }}</view>
  </view>
</view>
.content {
  padding: 10rpx;
  display: flex;
  justify-content: space-between;
}
.content-left {
  display: flex;
  width: calc(50% - 10rpx);
  flex-direction: column;
}
.content-right {
  display: flex;
  width: calc(50% - 10rpx);
  flex-direction: column;
}
.item {
  padding: 10rpx;
  margin-bottom: 10rpx;
  border: 1rpx solid #ccc;
}
.noShow {
  width: calc(50% - 10rpx);
  position: absolute;
  left: 10000px;
  bottom: 10000px;
}
this.$nextTick(() => {
  let elLeftHeight = 0;
  let elRightHeight = 0;
  this.list.forEach((item,index) => {
    if (elLeftHeight > elRightHeight) {
      this.listRight.push(item);
      elRightHeight += this.$refs.list[index].$el.clientHeight;
    } else {
      this.listLeft.push(item);
      elLeftHeight += this.$refs.list[index].$el.clientHeight;
    }
  });
});

過程及原理詳細解析

css

  1. 使用flex布局設置一個兩欄布局(根據(jù)實際開發(fā)情況可設置多欄布局),每一欄縱向排列
  2. 單獨設置一個絕對位置的選擇器,使其雖然渲染了,但頁面上不展示

html

  1. 利用flex布局(也可其他方式,無所謂)形成一個基本的兩欄布局
  2. 為渲染到頁面但因定位不會展示在頁面的模塊設置ref(也可在js中使用document直接獲取,看你喜好)

js

  1. 分別定義兩個空數(shù)組用來存儲兩欄要展示的數(shù)據(jù),再將所有數(shù)據(jù)存放在另一個單獨的數(shù)組中,渲染到未展示在頁面上的絕對定位的模塊(為了嚴謹,需將該模塊寬度與兩欄布局的每一欄寬度相同),依次可計算每條數(shù)據(jù)的高度。
  2. 按照算法思路,設置左右欄高度都為0,遍歷數(shù)據(jù),對左右欄高度做判斷,將數(shù)據(jù)寫入到較低高度的一欄中(相同高度寫入左邊),寫入后將該數(shù)據(jù)的展示高度添加到該欄中

較優(yōu)解:grid布局實現(xiàn)

這種方法不需要對數(shù)據(jù)進行遍歷傳入渲染,瀏覽器自動對內容堆疊排放

首先使用grid布局實現(xiàn)兩欄(或多欄)布局

vue+uniapp的實現(xiàn)

.content {
  padding: 10rpx;
  display:grid;
  grid-auto-rows: 10rpx;
  column-gap: 10rpx;
  grid-template-columns: 1fr 1fr;
  align-items: start;
}
.content-item {
  border: 1rpx solid #000;
  padding: 10rpx;
}
<view class="content">
  <view class="content-item" ref="content" v-for="item in list" :key="item.index">{{ item.content }}</view>
</view>
this.$nextTick(()=>{
  this.list.forEach((item, index) => {
    this.$refs.content[index].$el.style.gridRowEnd = `span ${Math.ceil(this.$refs.content[index].$el.clientHeight / 5) + 1}`
    console.log(this.$refs.content[index].$el.style.gridRowEnd);
  })
})
image.png

過程及原理詳細解析

css:

  1. 使用css的grid布局設定基本兩欄布局(根據(jù)實際開發(fā)情況可設置多欄布局)
  2. 使用align-items: start設定縱向的排列方式為從上到下依次排列
  3. 使用grid-auto-rows: 10rpx屬性設置網(wǎng)格每行高度為10rpx

js:

  1. 使用ref獲取每個內容模塊的高度(我用的vue所以使用的是ref,js也可使用document來獲?。?/li>
  2. 使用 clientHeight / 5 ,根據(jù)每個模塊的高度去除以css中設置的每個網(wǎng)格高度(示例代碼用的uniapp的單位rpx,clientHeight獲取的是px,10rpx==5px),得到這個模塊縱向占據(jù)網(wǎng)格的數(shù)量,
  3. 使用js向其添加行內樣式 grid-row-end: span [Number],該屬性設置該模塊縱向占據(jù)的網(wǎng)格數(shù)量,瀏覽器渲染時會將其自動向下堆疊
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容