Pinterest 瀑布布局是怎麼實現的?

是不是要用到js?


依靠 JavaScript + CSS 是肯定的。

jQuery 有一個插件,叫 jQuery Masonry (http://masonry.desandro.com/)

可以輕鬆地將默認 inline-block 布局的頁面塊轉化瀑布流格式,只需要一行代碼,可以實現很多種形式的瀑布流。

所以,如果不關心底層的實現原理,會用它就足夠了。

如果你想進一步了解它背後的機制,不妨研究下 Masonry 的源代碼,很輕量,不難發現它的原理:

  1. 每個塊被載入完成之後,它的長和寬就可以認為是固定的。

    注意:有時候可能是需要塊中的圖片被載入才能確定塊的大小,沒錯,Masonry 提供了一個方法叫 imagesLoaded,可參考:http://masonry.desandro.com/demos/images.html

    但是一般不推薦這樣,因為圖片載入可能是個很耗時的過程,特別是瀑布流這樣的有大量圖片的頁面。那麼一般是將圖片的 height 信息記錄在資料庫中,顯示的時候直接就確定了大小而不需要等待圖片載入。

  2. Masonry 會根據每個塊的大小進行調整位置。

    對於瀑布流頁面,可以認為是固定列寬。那麼問題就可以轉化為到找到當前最小的 x、y 坐標,然後在這裡填充下一個元素。

    沒錯,經過 Masonry 布局之後,每個塊元素會被加上一些 style 屬性,分別是

    position:absolute; top:xx px; left: yy px;

    這裡的 xx 和 yy 為計算出的坐標。

    也就是說,這個插件把整個布局的元素全部轉化為 absolute 布局,那麼他的位置相對父級(relative 布局)就是一個完全可以靈活控制的屬性。
  3. Masonry 可以說是為瀑布流頁面量身打造的,一般情況下,沒必要自己再去實現。

    為什麼?因為它還有很多貼心的細節。

    比如在不同窗口寬度下,瀑布流區域的列數是會變化的。去花瓣網(http://huaban.com/),Pinterest(http://pinterest.com)看看吧。縮放頁面就可以看出來。

    注意:如果你也用 Masonry 的話,千萬不要把瀑布流的容器設置成 fixed-width,設置一個 min-width 就可以了。否則他是不會自動調整列寬的。


實現瀑布流主要有三種方法,按常用的排列,依次有:

1、絕對定位布局:關鍵是取得圖片的高度,然後依次絕對定位每張圖片(top、left),這種方法是目前用的比較多,因為要一直算定位,所以性能不高;

2、固定列數的浮動布局:載入頁面時取頁面寬度,算出可以有的列數,然後依次給每列插入圖片,像發撲克牌一樣,這種方法不用知道高度,比上一種方法簡單多了;

3、利用CSS3列(column)布局:這個最省事了,不過兼容是一個問題;

參考文章:

瀑布流布局淺析(一):三種實現方式比較

淺談個人在瀑布流網頁的實現中遇到的問題和解決方法

折騰:瀑布流布局(基於多欄列表流體布局實現) ? 張鑫旭

……

具體的就自己搜索一下吧。


絕大多數都是用絕對定位,因為權衡下來這種方式最靠譜。

這裡有一份實現的源碼可以參考:

bootstrap-waterfall/bootstrap-waterfall.js at master · Mystist/bootstrap-waterfall · GitHub


推薦閱讀:

如何看待 Pinterest 的相似視覺搜索結果?
Pinterest 好在哪裡?
中國版的 Pinterest 有哪些?
Pinterest 的推薦流量怎麼可能會越過 Twitter?

TAG:Pinterest | 流式布局 |