Pinterest 瀑布布局是怎麼實現的?
01-29
是不是要用到js?
依靠 JavaScript + CSS 是肯定的。
jQuery 有一個插件,叫 jQuery Masonry (http://masonry.desandro.com/)
可以輕鬆地將默認 inline-block 布局的頁面塊轉化瀑布流格式,只需要一行代碼,可以實現很多種形式的瀑布流。
所以,如果不關心底層的實現原理,會用它就足夠了。如果你想進一步了解它背後的機制,不妨研究下 Masonry 的源代碼,很輕量,不難發現它的原理:- 每個塊被載入完成之後,它的長和寬就可以認為是固定的。注意:有時候可能是需要塊中的圖片被載入才能確定塊的大小,沒錯,Masonry 提供了一個方法叫 imagesLoaded,可參考:http://masonry.desandro.com/demos/images.html
但是一般不推薦這樣,因為圖片載入可能是個很耗時的過程,特別是瀑布流這樣的有大量圖片的頁面。那麼一般是將圖片的 height 信息記錄在資料庫中,顯示的時候直接就確定了大小而不需要等待圖片載入。
- Masonry 會根據每個塊的大小進行調整位置。對於瀑布流頁面,可以認為是固定列寬。那麼問題就可以轉化為到找到當前最小的 x、y 坐標,然後在這裡填充下一個元素。沒錯,經過 Masonry 布局之後,每個塊元素會被加上一些 style 屬性,分別是 position:absolute; top:xx px; left: yy px;
這裡的 xx 和 yy 為計算出的坐標。
也就是說,這個插件把整個布局的元素全部轉化為 absolute 布局,那麼他的位置相對父級(relative 布局)就是一個完全可以靈活控制的屬性。 - 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?