Pinterest 瀑布流布局插件布局是怎么实现的

纯CSS实现瀑布流布局 - 为程序员服务
纯CSS实现瀑布流布局
瀑布流布局有一个专业的英文名称
Masonry Layouts
。瀑布流布局已经有好多年的历史了,我最早知道这个名词的时候大约是在2012年,当时
网站的布局就是使用的这种流式布局,简言之像Pinterest网站这样的布局就称之为瀑布流布局,也有人称之为Pinterest 布局。
瀑布流布局其核心是基于一个网格的布局,而且每行包含的项目列表高度是随机的(随着自己内容动态变化高度),同时每个项目列表呈堆栈形式排列,最为关键的是,堆栈之间彼此之间没有多余的间距差存大。还是上张图来看看我们说的瀑布流布局是什么样子。
当初要实现这样的布局都是依赖于JavaScript来实现,所以当时出现过很多实现
等都是非常有名的插件。但使用纯CSS来实现,当时还是非常困难的,不管是使用
inline-block
布局都无法很好的控制列表项目堆栈之间的间距。最终得到的效果就像下面这样:
现在距离2012年已经过去了五个年头,CSS的技术更新也是日新月异,在这几年当中出现了很多新的布局方法,比如多列布局
multi-columns
、Flexbox布局以及今年浏览器支持有Grid布局。早前在《
》一文中有对这些布局做过阐述。既然CSS的布局有这么多的变化,那么今天有没有不借助任何JavaScript(纯CSS方案)能否实现瀑布流布局?答案是肯定的,接下来的内容,我们就使用不同的CSS布局方案来实现瀑布流布局。
Multi-columns
首先最早尝试使用纯CSS方法解决瀑布流布局的是CSS3 的
。其最早只是用来用来实现文本多列排列(类似报纸杂志样的文本排列)。但对于前端同学来说,他们都是非常具有创意和创新的,有人尝试通过Multi-columns相关的属性
column-count
column-gap
break-inside
来实现瀑布流布局。
比如我们有一个类似这样的HTML结构:
&div class="masonry"&
&div class="item"&
&div class="item__content"&
&div class="item"&
&div class="item__content"&
&!-- more items --&
div.masonry
是瀑布流的容器,其里面放置了
。为了节约篇幅,上面代码仅列了两个。结构有了,现在来看CSS。在
column-count
column-gap
,前者用来设置列数,后者设置列间距:
.masonry {
column-count: 5;
column-gap: 0;
上面控制了列与列之间的效果,但这并不是最关键之处。当初纯CSS实现瀑布流布局中最关键的是堆栈之间的间距,而并非列与列之间的控制(说句实话,列与列之间的控制
之类的就能很好的实现)。找到实现痛楚,那就好办了。或许你会问有什么CSS方法可以解决这个。在CSS中有一个
break-inside
属性,这个属性也是实现瀑布流布局最关键的属性。
break-inside:
box-sizing: border-
padding: 10
break-inside:avoid
为了控制文本块分解成单独的列,以免项目列表的内容跨列,破坏整体的布局。当然为了布局具有
,可以借助
属性,在不同的条件下使用
column-count
设置不同的列,比如:
.masonry {
column-count: 1; // one column on mobile
@media (min-width: 400px) {
.masonry {
column-count: 2; // two columns on larger phones
@media (min-width: 1200px) {
.masonry {
column-count: 3; // three columns on...you get it
&!-- etc. --&
比如下面的这个示例:
看到上面示例的效果,这个时候是不是有点成就感了,是不是觉得CSS更神奇了?
Flexbox布局到今天已经是使用非常广泛的,也算是很成熟的一个特性。那接下来我们就看Flexbox怎么实现瀑布流布局。如果你从未接触过Flexbox相关的属性,那建议你
阅读。如果你觉得这里信息量过于太多,那强列建议你阅读下面几篇文章,阅读完之后你对Flexbox相关属性会有一个彻底的了解:
上面这几篇文章告诉了你有关于Flexbox的一切:
接下来回到我们今天的正题当中,使用Flexbox实现瀑布流布局有两种方案。
一个主要的列容器
结构依旧和Multi-columns小节中展示的一样。只是在
容器中使用的CSS不一样:
.masonry {
flex-flow:
width: 100%;
height: 800
column-count
来控制列,这里采用
来控制列,并且允许它换行。这里关键是容器的高度,示例中显式的设置了
属性,当然除了设置
值,还可以设置
容器的高度和浏览器视窗高度一样。记住,这里
可以设置成任何高度值(采用任何的单位),但不能不显式的设置,如果没有显式的设置,容器就无法包裹住项目列表。
使用Flexbox布局,对于
可以不再使用
break-inside:avoid
,但其它属性可以是一样。同样的,响应式设置,使用Flexbox实现响应式布局比多列布局要来得容易,他天生就具备这方面的能力,只不过我们这里需要对容器的高度做相关的处理。前面也提到过了,如果不给
容器显式设置高度是无法包裹项目列表的,那么这里响应式设计中就需要在不同的媒体查询条件下设置不同的高度值:
.masonry {
@media screen and (min-width: 400px) {
.masonry {
height: 1600
@media screen and (min-width: 600px) {
.masonry {
height: 1300
@media screen and (min-width: 800px) {
.masonry {
height: 1100
@media screen and (min-width: 1100px) {
.masonry {
height: 800
同样来看一个示例效果:
这个解决方案有一个最致命的地方,就是需要显式的给
,特别对于响应式设计来说这个更为不友好。而且当我们的项目列表是动态生成,而且内容不好控制之时,这就更蛋疼了。那么有没有更为友好的方案呢?
前面说到过Flexbox有两种方案,那咱们先来看方案二,再来回答这个问题。
单独的列容器
这个方案,我们需要对我们的HTML结构做一个变更。变更后的HTML结构看起来像这样:
&div class="masonry"&
&div class="column"&
&div class="item"&
&div class="item__content"&
&!-- more items --&
&div class="column"&
&div class="item"&
&div class="item__content"&
&!-- more items --&
&div class="column"&
&div class="item"&
&div class="item__content"&
&!-- more items --&
不难发现,在
外面包了一层
div.column
div.column
称为列表项目的单独容器。在这个解决方案中,
display:flex
属性将其设置为Flex容器,不同的是
设置为行(
flex-direction:row
设置为列(
flex-direction
.masonry {
flex-direction:
flex-direction:
width: calc(100%/3);
这里有一个需要注意,在
方法来控制每个列的宽度,如果你希望是三列,那么可以设置
width: calc(100% / 3)
实际中根据自己的设计来设置
.masonry {
flex-direction:
flex-direction:
width: calc(100%/3);
这种方案对应的响应式设计,需要在不同的媒体查询下修改
值,比如:
.masonry {
flex-direction:
@media only screen and (min-width: 500px) {
.masonry {
flex-direction:
flex-flow:
width: 100%;
@media only screen and (min-width: 500px) {
width: calc(100%/5);
效果如下:
从实战结果已经告诉你答案了。只不过在结构上变得冗余一点。
将是布局当中的一把利剑,也可以说是神器,特别是今年得到了
。记得去年在CSSConf分享后,有同学问我Grid是否能实现瀑布流的布局。说实话,虽然Grid对于布局而言是非常的强大,但要很好的实现瀑布流布局还是非常的蛋疼。@Rachel Andrew在她
中也特意提到过实现瀑布流的方案。从文章中摘出有关于瀑布流布局的那部分内容。
Grid制作瀑布流,对于结构而言和Multi-columns示例中的一样。只不过在
display:grid
来进行声明:
.masonry {
grid-gap: 40
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: minmax(50px, auto);
较为蛋疼,需要分别通过
grid-column
来指定列表项目所在的区域,比如:
.masonry & div:nth-child(1) {
grid-row: 1 / 4;
grid-column: 1;
.masonry & div:nth-child(2) {
grid-row: 1 / 3;
grid-column: 2;
将效果Fork过来:
在Grid中有自动排列的算法的属性:
如果没有明确指定网格项目位置,网格会按自动排列算法,将它最大化利用可用空间
如果在当前行没有可用位置,网格会自动搜索下一行,这样会造成一定的差距,浪费可用空间
grid-auto-flow
,可以切换搜索顺序
grid-auto-flow
还可以接受另一个关键词。默认情况下,其值是
,但我们可以将其显式的设置为
,让网格项目试图自动填补所有可用的空白空间
言外之意,Grid中
对于实现瀑布流布局有很大的帮助。不过对于堆栈(列表项目)高度不能友好的控制。
这篇文章主要介绍了如何使用纯CSS实现瀑布流的布局。文章简单介绍了三种实现方案:Multi-columns、Flexbox和Grid。从上面的示例或者实现手段而言,较我友好的是Flexbox的方案。当然,随着CSS Grid特性的完善,使用Grid实现瀑布流布局将会变得更为简单和友好。那让我们拭目以待。当然如果你觉得这些方案都不太好,你可以依旧可以考虑
。如果你有更好的解决方案,也希望能在下面的评论中与我们一起分享。
常用昵称“大漠”,W3CPlus创始人,目前就职于手淘。对HTML5、CSS3和Sass等前端脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《
如需转载,烦请注明出处:
原文地址:, 感谢原作者分享。
您可能感兴趣的代码基于Bootstrap仿Pinterest的网格瀑布流插件效果演示_jQuery之家-自由分享jQuery、html5、css3的插件库
基于Bootstrap仿Pinterest的网格瀑布流插件效果演示Pinterest/瀑布流布局
一 加载页面时,先页面中对已有元素进行定位。
使用对象保存每一列的列高度和列索引如:var column = {index:0, height:0};
使用列数组存放来这些对象。如:var columns = [column1,column2....];
使用cloumns.sort(function(x,y){return x.height - y.height}); 可以找出最短/最长高度的列的索引。
元素left= 列索引* 列宽 ; 元素top = 最短一列的高度;
二 鼠标滚动到最短一列的底部时动态加载数据。
if(文档scrollTop + 视口高度 & 容器距离文档顶部位置 + 最短一列的高度){
  加载新内容
使用htmlElement.chidren属性可以只返回&htmlElement&的 元素类型子节点,不过IE中还会返回注释节点。htmlElement.childNodes 属性在非IE中除了返回元素类型子节点外,还返回注释和文本类型的子节点。要在childNodes里获取html元素节点,一般通过遍历然后比较 nodeType 进行过滤。每次 waterfall.appendChild(htmlElement.chidren[i]);&& & htmlElement.chidren 里的元素个数减一,后面的元素自动向前移。
&!doctype html&
&meta charset="gb2312"&
&title&Pinterest/瀑布流布局&/title&
.waterfall{position: margin:0}
.waterfall .item{width:210 display:none}
.waterfall .item:hover{opacity: 0.9}
.loading{text-align: padding:20px 0 120 }
&a href="javascript:void(null)" onClick="blank()"&open&/a&
&h1&Pinterest/瀑布流布局&/h1&
&li&加载页面,动态数据块,透明度为0, 对已有元素进行定位&/li&
&li&问个瀑布流中的滚动加载数据问题? 页面高度(scrollHeight)- 浏览器视口高度(offsetHeight) + 浏览器滚动高度(scrollTop)&/li&
&li&鼠标滚动到最短一列的底部时加载数据&/li&
&h2&document clientWidth:&/h2&
document.write(document.body.clientWidth + "&br&" + document.documentElement.clientWidth);
var data = '
&div class="item"& \
&img src="http://pic4.xihuan.me/dr/192_287_90/t02e9a2.jpg" width="191" height="287"& \
&div class="item"& \
&img src="http://pic2.xihuan.me/dr/192_288_90/t023a00b8fd90f13bf6.jpg" width="191" height="288"&\
&div class="item"&\
&img src="http://pic2.xihuan.me/dr/192_128_90/tfa0049796.jpg" width="192" height="128"&\
&div class="item"& \
&img src="http://pic2.xihuan.me/dr/192_136_90/t02fba1b4.jpg" width="192" height="136"& \
&div class="item"& \
&img src="http://pic3.xihuan.me/dr/192_288_90/tb0305fe.jpg" width="192" height="288"&\
&div class="item"&\
&img src="http://pic1.xihuan.me/dr/192_267_90/t0285eade.jpg" width="191" height="267"&\
&div class="item"& \
&img src="http://pic3.xihuan.me/dr/192_144_90/t02fa12b10de9a6d67a.jpg" width="192" height="144"&\
&div class="item" & \
&img src="http://pic4.xihuan.me/dr/192_192_90/t025e949d.jpg" width="192" height="192"& \
&div class="item"&\
&img src="http://pic0.xihuan.me/dr/192_266_90/t02b313f975b4fe3068.jpg" width="192" height="266"&\
&div class="item" & \
&img src="http://pic0.xihuan.me/dr/192_302_90/t0214baf4ab88314b2b.jpg" width="192" height="302"&\
&div class="item"&\
&img src="http://pic2.xihuan.me/dr/192_256_90/t020b4d6b44ee7f086d.jpg" width="192" height="256"&\
&div class="item"& \
&img src="http://pic4.xihuan.me/dr/192_288_90/te08f88a459.jpg" width="192" height="288"& \
&div class="item"&\
&img width="191" height="251" src="http://pic0.xihuan.me/dr/192_251_90/t02af8a0a7824408fcc.jpg"&\
&div class="item"&\
&img width="192" height="192" src="http://pic0.xihuan.me/dr/192_192_90/t02664c86dbada6a50e.jpg"& \
&div class="item"& \
&img width="192" height="152" src="http://pic0.xihuan.me/dr/192_152_90/t02c218bfbdd123c42b.jpg"& \
&div class="item"& \
&img width="191" height="241" src="http://pic3.xihuan.me/dr/192_241_90/t026cd38.jpg"&\
&div class="item"&\
&img width="191" height="288" src="http://pic3.xihuan.me/dr/192_288_90/tf31c6c0c.jpg"&\
&div class="item" & \
&img width="191" height="427"
src="http://pic2.xihuan.me/dr/192_427_90/t023fd53d.jpg"& \
&div class="item" &\
&img height="176" width="192" src="http://pic4.xihuan.me/dr/192_176_90/t02b7c5d.jpg"&\
&h2& document.documentElement.clientWidth&/h2&
&p& document.body.clientWidth
body 元素宽度&br&
document.documentElement.clientWidth html元素宽度
&h2&htmlElement.chidren&/h2&
使用htmlElement.chidren属性可以只返回&htmlElement&的元素类型子节点,不过IE中还会返回注释节点。htmlElement.childNodes 属性在非IE中除了返回元素类型子节点外,还返回注释和文本类型的子节点。要在childNodes里获取html元素节点,一般通过遍历然后比较nodeType 进行过滤。
每次 waterfall.appendChild(htmlElement.chidren[i]);
htmlElement.chidren 里的元素个数减一,后面的元素自动向前移。
&div class="wrap"&
&div id="Waterfall" class="waterfall"&
&div class="item"&
&img src="http://pic4.xihuan.me/dr/192_287_90/t02e9a2.jpg" width="191" height="287"&
&div class="item"&
&img src="http://pic2.xihuan.me/dr/192_288_90/t023a00b8fd90f13bf6.jpg" width="191" height="288"&
&div class="item"&
&img src="http://pic2.xihuan.me/dr/192_128_90/tfa0049796.jpg" width="192" height="128"&
&div class="item"&
&img src="http://pic2.xihuan.me/dr/192_136_90/t02fba1b4.jpg" width="192" height="136"&
&div class="item"&
&img src="http://pic3.xihuan.me/dr/192_288_90/tb0305fe.jpg" width="192" height="288"&
&div class="item"&
&img src="http://pic1.xihuan.me/dr/192_267_90/t0285eade.jpg" width="191" height="267"&
&div class="item"&
&img src="http://pic3.xihuan.me/dr/192_144_90/t02fa12b10de9a6d67a.jpg" width="192" height="144"&
&div class="item" &
&img src="http://pic4.xihuan.me/dr/192_192_90/t025e949d.jpg" width="192" height="192"&
&div class="item"&
&img src="http://pic0.xihuan.me/dr/192_266_90/t02b313f975b4fe3068.jpg" width="192" height="266"&
&div class="item" &
&img src="http://pic0.xihuan.me/dr/192_302_90/t0214baf4ab88314b2b.jpg" width="192" height="302"&
&div class="item"&
&img src="http://pic2.xihuan.me/dr/192_256_90/t020b4d6b44ee7f086d.jpg" width="192" height="256"&
&div class="item"&
&img src="http://pic4.xihuan.me/dr/192_288_90/te08f88a459.jpg" width="192" height="288"&
&div class="item"&
&img width="191" height="251" src="http://pic0.xihuan.me/dr/192_251_90/t02af8a0a7824408fcc.jpg"&
&div class="item"&
&img width="192" height="192" src="http://pic0.xihuan.me/dr/192_192_90/t02664c86dbada6a50e.jpg"&
&div class="item"&
&img width="192" height="152" src="http://pic0.xihuan.me/dr/192_152_90/t02c218bfbdd123c42b.jpg"&
&div class="item"&
&img width="191" height="241" src="http://pic3.xihuan.me/dr/192_241_90/t026cd38.jpg"&
&div class="item"&
&img width="191" height="288" src="http://pic3.xihuan.me/dr/192_288_90/tf31c6c0c.jpg"&
&div class="item" &
&img width="191" height="427"
src="http://pic2.xihuan.me/dr/192_427_90/t023fd53d.jpg"&
&div class="item" &
&img height="176" width="192" src="http://pic4.xihuan.me/dr/192_176_90/t02b7c5d.jpg"&
&div class="loading" id="loading"&正在加载&&&/div&
var tool = {
//此方法为了避免在 ms 段时间内,多次执行func。常用 resize、scoll、mousemove等连续性事件中
buffer: function(func, ms, context){
function(){
if(buffer)
buffer = setTimeout(function(){
func.call(this)
/*读取或设置元素的透明度*/
opacity: function(elem, val){
var setting = arguments.length & 1;
if("opacity" in elem.style){//elem.style["opacity"] 读取不到CSS class中的值
return setting ? elem.style["opacity"] = val : elem.style["opacity"];
if(elem.filters && elem.filters.alpha) {
return setting ? elem.filters.alpha["opacity"] = val*100 : elem.filters.alpha["opacity"]/100;
//获取或设置文档对象的scrollTop
//function([val])
documentScrollTop: function(val){
var elem =
return (val!== undefined) ?
elem.documentElement.scrollTop = elem.body.scrollTop = val :
Math.max(elem.documentElement.scrollTop, elem.body.scrollTop);
//function (elem) 获取elem在页面中的坐标
//return {top:xxx,left:xxx}
offset: function (elem){
if(!(elem && elem.offsetTop))
top = elem.offsetT
left = elem.offsetL
while(elem = elem.offsetParent){
top += elem.offsetT
left += elem.offsetL
return {top:top, left:left};
get: function(id){
return document.getElementById(id);
addEventListener: function(elem, type, handel){
if(elem.addEventListener){
elem.addEventListener(type, handel, false);
elem.attachEvent("on"+type, function(){
handel.call(elem, window.event);
function wrap(elem){
return new DomWrap(elem);
function DomWrap(elem){
this.core =
this.dom =
DomWrap.prototype={
on: function(type, handel){
this.core.addEventListener(this.dom, type, handel);
//Waterfall
(function(ns, dom){//dom:DomWrap
//静态私有成员
var viewportHeight = document.documentElement.clientH
var minHeight = 0;
var columnCount = 5;
var columnWidth= 210;
var cloumns = [];
var waterfall = "";
var staticElems = [];
var baseTop = 0;
function init(container){
waterfall = tool.get(container);
staticElems = waterfall.
baseTop = tool.offset(waterfall).
for(var i=0; i& columnC i ++){
cloumns[i] = {index:i, height:0};
waterfall.style.width = (columnWidth*columnCount)+"px";
dom(window).on("scroll",tool.buffer(onscroll,500));
position(staticElems);
//设置元素位置
function position(elems, append){
var left, top, cssT
var appedElem =
var sortedCloumns = [];
for(var i=0, n= elems. i&) {
if(!(elems[i] && elems[i].nodeType ===1))
cloumns.sort(function(x,y){return x.height - y.height});
index = cloumns[0].
left = index * columnWidth
top = cloumns[0].
cssText = "display: position: left:" + left + " top:" + top + "px";
elems[i].style.cssText = cssT
if(append){
apendItem = elems[i];
waterfall.appendChild(apendItem);
cloumns[0].height += apendItem.offsetH
cloumns[0].height += elems[i].offsetH
cloumns.sort(function(x,y){return x.height - y.height});
minHeight = cloumns[0].
waterfall.style.height = cloumns[cloumns.length-1].height + "px";
function appendItem(){
var fragment = document.createElement("div");
fragment.innerHTML =
position(fragment.children,true);
function onscroll(){
var scrollTop = tool.documentScrollTop();
if(scrollTop + viewportHeight & baseTop + minHeight ) {
//console.log("loading");
appendItem();
ns.watferfall =
}( window, wrap));
watferfall("Waterfall");
阅读(...) 评论()因为之前也没机会接触瀑布流式布局,但是看了Pinterest和之后,就急切想知道是怎么做到的,真的蛮好看的哈哈、
直接上代码吧
嗯 不对 先上效果图:
html部分:
&!DOCTYPE html&
&meta charset="UTF-8"&
&title&&/title&
&style type="text/css"&
/*使用通配符将内外边距都设置为零, 这样看着好看*/
margin: 0px;
padding: 0px;
/*将主容器的布局方式设置为相对布局,一下方式可设置container为水平居中,详见:http://www.zhangxinxu.com/wordpress/2013/11/margin-auto-absolute-%E7%BB%9D%E5%AF%B9%E5%AE%9A%E4%BD%8D-%E6%B0%B4%E5%B9%B3%E5%9E%82%E7%9B%B4%E5%B1%85%E4%B8%AD/*/
#container {
position: relative;
bottom: 0;
margin: auto;
/*定制box尺寸*/
padding: 7px;
float: left;
box-sizing: border-box;
width: 212px;
/* 图片尺寸+wrapper内边距+box内边距 */
/*将承载图片的容器定制颜色及边框大小和圆角*/
.wrapper {
padding: 5px;
box-shadow: 0 0 5px #ccc;
border-radius: 5px;
font-size: 0; /*消除行内元素的间隙*/
.pic img {
width: 100%;
height: auto;
.wrapper & p {
color: #999;
background: #FAFAFA;
font-size: 14px;
padding-top: 5px;
&div id="container"&
&div class="box"&
&div class="wrapper"&
&div class="pic"&
&img src="imgs/1.jpg"&
&p&此处为文字说明&/p&
&div class="box"&
&div class="wrapper"&
&div class="pic"&
&img src="imgs/2.jpg"&
&p&此处为文字说明&/p&
&div class="box"&
&div class="wrapper"&
&div class="pic"&
&img src="imgs/3.jpg"&
&p&此处为文字说明&/p&
&div class="box"&
&div class="wrapper"&
&div class="pic"&
&img src="imgs/4.jpg"&
&p&此处为文字说明&/p&
&div class="box"&
&div class="wrapper"&
&div class="pic"&
&img src="imgs/5.jpg"&
&p&此处为文字说明&/p&
&div class="box"&
&div class="wrapper"&
&div class="pic"&
&img src="imgs/6.jpg"&
&p&此处为文字说明&/p&
&div class="box"&
&div class="wrapper"&
&div class="pic"&
&img src="imgs/7.jpg"&
&p&此处为文字说明&/p&
&div class="box"&
&div class="wrapper"&
&div class="pic"&
&img src="imgs/8.jpg"&
&p&此处为文字说明&/p&
&div class="box"&
&div class="wrapper"&
&div class="pic"&
&img src="imgs/9.jpg"&
&p&此处为文字说明&/p&
window.onload = function() { // 一定要页面加载完成再调用
waterFall.init('container', 'box');
window.onresize = function() {
waterFall.init('container', 'box');
var waterFall = {
init: function(container, box) {
var windowWidth = window.innerW
var oContainer = document.getElementById(container);
oContainer.style.width = windowWidth & 1200 ? 1200 + 'px' : windowWidth + 'px';
var oBoxs = oContainer.getElementsByClassName(box);
var boxWidth = oBoxs[0].offsetW
var containerWidth = oContainer.offsetW
var col = containerWidth / boxW // box列数
var arrHeight = []; // 用来记录每列已添加box的高度
for (var i = 0; i & oBoxs. i++) {
oBoxs[i].style.position = "absolute"; // 给每个box定义布局方式为绝对布局
var boxHeight = oBoxs[i].offsetH
if (i & col - 1) { // 第一行
arrHeight.push(oBoxs[i].offsetHeight);
oBoxs[i].style.top = 0;
oBoxs[i].style.left = i * boxWidth + 'px';
var minBoxHeight = Math.min.apply(null, arrHeight); // 求出arrHeight中最小高度的那一列
var index = this.getIndex(minBoxHeight, arrHeight); // 获取以上最小高度那列的索引
oBoxs[i].style.top = minBoxHeight + 'px';
oBoxs[i].style.left = boxWidth * index + 'px';
arrHeight[index] += oBoxs[i].offsetH // 由于已添加box,所以此处更新arrHeight中已添加box那一列的高度值
getIndex: function(val, arr) { // 得到索引
for (var i = 0 ; i & arr. i++) {
if (val == arr[i]) {
阅读(...) 评论()}

我要回帖

更多关于 瀑布流布局 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信