网站布局--瀑布流式布局
瀑布流式布局简介
现在越来越流行一种瀑布流式布局的页面布局方式,希望你没有对这个名字陌生,看张图相信你就知道它是什么了。
怎么样,是不是很熟悉,越来越多的网站采用这种布局,比如 Pinterest (貌似是最早使用这种布局的网站了),Mark之,蘑菇街,点点网,哇哦等等。
瀑布式流式布局,这个名字是很形象的,这种布局适合于小数据块,每个数据块内容相近且没有侧重。通常,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部。这种布局可以说是扩展了原始的格子布局,给用户更加自由,灵活的感觉,便于浏览。
几种实现方式
作为前端人员,我们肯定也要紧随用户喜好,抓住用户眼球,那么整理一下这种布局的三种实现方式:
(1)传统的多列浮动
· 各列固定宽度,并且左浮动;
· 一列中的数据块为一组,列中的每块依次排列;
· 更多数据加载时,需要分别插入到不同的列中;
优点:
· 布局简单;
· 不用明确数据块的高度,自适应即可。
缺点:
· 不用明确数据块的高度,自适应即可。
缺点:
· 列数固定,嵌套较多
· 滚动加载更多数据时,需要指定插入到第几列中,不方便。
(2)CSS3样式定义法
我们将要用到的是CSS3新加的column属性,通过指定容器的列个数column-count,列间距column-gap,列中间的边框(间隔边线)column-rule,列宽度column-width实现。
代码如下:
#container{background-color:#faba8c;
column-count:3; column-gap:50px; column-rule: 10px solid #fff;column-width:150px;
-webkit-column-count:3; -webkit-column-gap:50px;-webkit-column-rule: 10px solid #fff;;-webkit-column-width:150px;
-moz-column-count:3; -moz-column-gap:50px;-moz-column-rule: 10px solid #fff;-moz-column-width:150px;}
当只设置 column-width 时,浏览器窗口小于一列宽度时,列中内容自动隐藏; 当只设置 column-count 时,平均计算每列宽度,列内内容超出则隐藏; 都设了 column-count 和column-width,浏览器会根据 count 计算宽度和 width 比较,取大的那个值作为每列宽度,然后当窗口缩小时,width 的值为每列最小宽度,这个得大家可以自己实践一下。
优点:
· 直接用CSS定义,方便快捷,是最好不过了;
· 扩展方便。
缺点:
· 目前仍有大部分浏览器不支持CSS3;
· CSS3这种方式的数据排列是从上到下排列到一定高度后,再把剩余元素依次添加到下一列;
· 鉴于以上,该方法目前局限于高端浏览器,更适合于文字的多栏排列。
(3)绝对定位
可以说是目前来说最优的一个方案了
优点:
· 方便添加数据内容,窗口变化,列数/数据块都会自动调整;
缺点:
· 需要知道数据块高度,如果其中包含图片,需要知道图片高度;
· JS 动态计算数据块位置,当窗口缩放频繁,可能会狂耗性能。
JS实现的主要思路:
有兴趣的同学可以看一下:
一个是对现有数据块进行排列计算各自所在的位置; 二是下拉滚动时,触发加载数据操作,并把数据添加到目标容器中。
1) 数据块排列,算法步骤简述下:
· 初始化时,对容器中已有数据块元素进行第一次计算,需要用户给定: a,容器元素 — 以此获取容器总宽度; b,列宽度; c,最小列数;
· 初始化时,对容器中已有数据块元素进行第一次计算,需要用户给定: a,容器元素 — 以此获取容器总宽度; b,列宽度; c,最小列数;
· 最终列数取的是容器宽度/列宽度和最小列数的最大值,这样保证了,当窗口很小时,仍然出现最小列数的数据;
· 获得列数后,需要保存每个列的当前高度,这样在添加每个数据块时,才知道起始高度是多少;
· 依次取容器中的所有数据块,先寻找当前高度最小的某列,之后根据列序号,确定数据块的left,top值,left 为所在列的序号乘以列宽,top 为所在列的当前高度,最后更新所在列的当前高度加上这个数据块元素的高度,至此,插入一个元素结束;
· 当所有元素插入完毕后,调整容器的高度为各列最大的高度值,结束依次调整;
· 性能效率上的注意点: a,如果当前正在调整中,又触发了 resize 事件,需要将上次调整暂停后执行这次调整(见 timedChunk 函数); b,resize 触发会很频繁,可以将回调函数缓存一段时候后执行,即当这段时间内多次触发了resize事件,但回调函数只会执行一次(见 S.buffer 函数)
· 当所有元素插入完毕后,调整容器的高度为各列最大的高度值,结束依次调整;
· 性能效率上的注意点: a,如果当前正在调整中,又触发了 resize 事件,需要将上次调整暂停后执行这次调整(见 timedChunk 函数); b,resize 触发会很频繁,可以将回调函数缓存一段时候后执行,即当这段时间内多次触发了resize事件,但回调函数只会执行一次(见 S.buffer 函数)
2) 异步加载数据,前面讲的是如何对容器中已有元素进行排列,但很多情况下,还需要不断加载新数据块,其实这个功能块也并不复杂,仅包含两个步骤:
· 绑定滚动事件,并确定预加载线高度值,即滚动到哪个高度后,需要去加载数据,其实这个就是列的最小高度值,这样当前滚动值和最小高度值比较一下即可判断出来,是否要触发加载数据;
· 加载数据,函数传参,能提供加载数据函数和停止加载(加载多少时停止)函数,以更方便的控制
· 绑定滚动事件,并确定预加载线高度值,即滚动到哪个高度后,需要去加载数据,其实这个就是列的最小高度值,这样当前滚动值和最小高度值比较一下即可判断出来,是否要触发加载数据;
· 加载数据,函数传参,能提供加载数据函数和停止加载(加载多少时停止)函数,以更方便的控制