成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

實現瀑布流布局,就這幾行代碼?

開發 前端
瀑布流布局是一種比較流行的頁面布局方式,表現為參差不齊的多欄卡片。跟網格布局相比,顯得更靈動,更具藝術氣息。

[[416106]]

瀑布流布局是一種比較流行的頁面布局方式,表現為參差不齊的多欄卡片。跟網格布局相比,顯得更靈動,更具藝術氣息。

瀑布流布局

實現瀑布流布局的方式有多種,比如multi-column布局,grid布局,flex 布局等。但是這些實現方式都有各自的局限性,代碼也略復雜。

其實,有個最原始、最簡單,也是兼容性最好的實現方式,那就是使用絕對定位。瀑布流布局的元素是一些等寬不等高的卡片,只要根據元素的實際寬高計算出自己的坐標位置就行了。

要計算坐標自然要用到 JavaScript,這就不是純 CSS 方案,對某些前端極客來講顯得不那么純粹。不過只要理清思路了,也用不了幾行代碼。本文就給出最近實現的一個版本。

  1. // 計算每個卡片的坐標 
  2. export function calcPositions({ columns = 2, gap = 7, elements }) { 
  3.   if (!elements || !elements.length) { 
  4.     return []; 
  5.   } 
  6.   const y = []; //上一行卡片的底部縱坐標數組,用于找到新卡片填充位置 
  7.   const positions = []; // 每個卡片的坐標數組 
  8.   elements.forEach((item, index) => { 
  9.     if (y.length < columns) { // 還未填滿一行 
  10.       y.push(item.offsetHeight); 
  11.       positions.push({ 
  12.         left: (index % columns) * (item.offsetWidth + gap), 
  13.         top: 0 
  14.       }); 
  15.     } else { 
  16.       const min = Math.min(...y); // 最小縱坐標 
  17.       const idx = y.indexOf(min); // 縱坐標最小的卡片索引 
  18.       y.splice(idx, 1, min + gap + item.offsetHeight); // 替換成新卡片的縱坐標 
  19.       positions.push({ 
  20.         left: idx * (item.offsetWidth + gap), 
  21.         topmin + gap 
  22.       }); 
  23.     } 
  24.   }); 
  25. // 由于采用絕對定位,容器是無法自動撐開的。因此需要計算實際高度,即最后一個卡片的top加上自身高度 
  26.   return { positions, containerHeight: positions[positions.length - 1].top + elements[elements.length - 1].offsetHeight }; 

上面這段代碼的作用就是計算每個卡片的left、top,以及容器的總高度。關鍵位置都有注釋,應該不難理解。

有了這幾行核心代碼,要想封裝成瀑布流組件就很容易了。以 Vue 為例,可以這樣封裝:

MasonryLite.vue

  1. <template> 
  2.   <div class="masonry-lite"
  3.     <slot></slot> 
  4.   </div> 
  5. </template> 
  6. <script> 
  7. import { calcPositions } from './index.js'
  8. export default { 
  9.   name'MasonryLite'
  10.   props: { 
  11.     gap: { 
  12.       type: Number, 
  13.       default: 12, 
  14.     }, 
  15.     columns: { 
  16.       type: Number, 
  17.       default: 2, 
  18.     }, 
  19.   }, 
  20.   data() { 
  21.     return {}; 
  22.   }, 
  23.   mounted() { 
  24.     this.doLayout(); 
  25.   }, 
  26.   methods: { 
  27.     doLayout() { 
  28.       const children = [...this.$el.querySelectorAll('.masonry-item')]; 
  29.       if (children.length === 0) { 
  30.         return
  31.       } 
  32.       const { positions, containerHeight } = calcPositions({ 
  33.         elements: children, 
  34.         columns: this.columns, 
  35.         gap: this.gap, 
  36.       }); 
  37.       children.forEach((item, index) => { 
  38.         item.style.cssText = `left:${positions[index].left}px;top:${positions[index].top}px;`; 
  39.       }); 
  40.       this.$el.style.height = `${containerHeight}px`; 
  41.     }, 
  42.   }, 
  43. }; 
  44. </script> 
  45. <style lang="scss" scoped> 
  46. .masonry-lite{ 
  47.   position: relative
  48. .masonry-item { 
  49.   position: absolute
  50. </style> 

使用組件:

  1. <MasonryLite> 
  2.   <div class="product-card masonry-item" v-v-for="(item, index) in items" :key="index"
  3.     <img :src="item.imageUrl" /> 
  4.     <header>{{ item.title }}</header> 
  5.   </div> 
  6. </MasonryLite> 

不過這樣其實還會有點問題,就是doLayout的執行時機。因為該方案基于絕對定位,需要元素在渲染完成后才能獲取到實際寬高。如果卡片內有延遲加載的圖片或者其他動態內容,高度會發生變化。這種情況下就需要在DOM更新后主動調用一次doLayout重新計算布局。

如果大家有更好的實現方案,歡迎交流!

代碼倉庫:https://github.com/kaysonli/masonry-lite

npm 包:masonry-lite

如果覺得對你有幫助,幫忙點個不要錢的star。

本文轉載自微信公眾號「1024譯站」,可以通過以下二維碼關注。轉載本文請聯系1024譯站公眾號。

 

責任編輯:武曉燕 來源: 1024譯站
相關推薦

2013-02-19 10:24:47

瀑布流布局CSS

2024-08-19 14:01:00

2012-05-02 13:53:00

JavaScript

2020-08-10 06:36:21

強化學習代碼深度學習

2021-10-18 09:09:16

數據庫

2021-06-22 09:55:05

代碼圖像技術

2021-04-15 11:10:40

GitHub代碼開發者

2020-09-29 10:09:43

Python文字識別編程語言

2024-06-04 14:20:47

數字化轉型數字化

2020-10-24 20:10:40

Python 開發編程語言

2020-07-07 07:55:53

web app數據科學機器學習

2023-11-01 10:36:19

2024-09-03 17:04:15

前端算法布局

2024-11-12 13:41:49

2021-01-29 10:57:57

新基建政策解讀智慧物流

2021-02-23 07:01:24

js小游戲技術

2023-10-27 11:38:09

PythonWord

2021-12-02 09:31:22

Python 代碼進度條

2024-01-10 14:45:46

Redis數據庫存儲

2023-12-24 22:52:26

PythonPPT代碼
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲巨乳自拍在线视频 | 欧美国产日韩一区二区三区 | 99免费在线| 久久成人久久 | 亚洲视频一区二区三区 | 亚洲精品久久区二区三区蜜桃臀 | 亚洲一区二区在线播放 | 国产精品美女一区二区三区 | 暖暖成人免费视频 | 国产精品美女久久久久久免费 | 亚洲成人999 | 国产日韩一区 | 狠狠骚 | 伊人久麻豆社区 | 亚洲视频在线一区 | 成年无码av片在线 | 91电影在线 | 亚洲人成人网 | 99re在线视频观看 | 人人性人人性碰国产 | 真人毛片 | 亚洲成人精品视频 | 国产欧美在线观看 | 涩爱av一区二区三区 | 免费簧片视频 | 一级免费在线视频 | 亚洲永久免费观看 | 中文字幕高清 | 国产婷婷综合 | av超碰| 久久精品无码一区二区三区 | 狠狠操电影 | 蜜臀网| 亚洲女优在线播放 | 影音先锋成人资源 | 欧美日韩亚洲一区 | 国产99免费 | 欧美极品在线观看 | 久久免费精品视频 | 久久精品网 | 精久久久 |