引言:瀑布流式布局(又名:瀑布图片墙),而Pinterest则是该布局的鼻祖。最该布局形式最初在国内默默无闻,但随着蘑菇街、点点和花瓣网等等的兴起...这样的布局方式也渐渐被人们所熟知。可能有人不经意要问,为什么现在越来越多的网站都这样效仿呢?我个人总结了2点:首先,图片+链接的方式,方便了用户浏览,也能清晰找到相关内容,可谓是一目了然。其次,看似散乱无序的碎片化内容,有着强大的视觉感染力。由于内容随机和不确定性,更能够诱导用户反复查看,有时更像是种“探宝”希望找到自己所喜欢的内容。
好了,说了一堆介绍,开始进入正题。其实,这个Demo很早就开始制作了,由于种种原因,一直没能写这文章。由于最近在做一个项目,需要用到这个布局方式,也所谓是不用不知道,一用才知道,看似没什么问题,但在实际应用中,还是有很多问题需要解决。所以,边做项目的同时,也把Demo优化、更新了下。
我写代码有个习惯,要么就是把代码注上相对容易理解的说明,要么就索性什么话都别说。当初在做这个Demo的时候,网上搜了很多资料。都没找到具体的制作方法,国内的网站,要么各种插件要么各种天书。我懂,我就不会去找资料,就是因为我不懂,所以我才去寻找“真相”。这次的代码,我基本都写上了注释。由于我也是从一个新手一步步的过来,所以应该也能易于其他人的理解吧。好了,废话说完,大家看代码吧。
CSS CODE:
*{margin:0px; padding:0px;} body{ font:12px/20px "Electrolize","Microsoft YaHei",tahoma,Arial,sans-serif; color:#666; text-shadow:0 1px 0 #FFF; background:url(images/body_bg.png);} ul,ol,li{ list-style:none;} a{ color:#666; text-decoration:none;} a:hover img{ opacity:.9;} #waterfall{ margin:50px auto; position:relative;} .picList{ width:222px; box-shadow:0 0 3px #CCC; background:#FFF; margin:0 6px 12px 6px; position:absolute; display:block;} .picList:hover{ box-shadow:1px 1px 5px #BBB;} .picList:hover .shareIcon{ display:block;} .picList .shareIcon{ display:none; width:100px; height:24px; background:url(images/share_icon.png) no-repeat; cursor:pointer; position:absolute; top:11px; right:11px; z-index:2; opacity:.9;} .picList .shareIcon:hover{ opacity:1;} .picThumbnail{ border-bottom:1px solid #EEE;} .picThumbnail a{ display:block; margin:11px; max-height:600px; overflow:hidden;} .picThumbnail img{ max-width:200px; display: block;} .picDescription{ padding:1px; text-align:center; padding:5px 10px; background:#F7F7F7; margin-top:1px;}
JQUERY CODE:
$(function(){ /*! * Ublue jQuery Waterfall * Create 2012.02.21 * Update 2012.10.18 ( 1.由于内容是absolute属性,导致元素偏离了文档,嵌入网页时无法撑开父级区域 2. 性能和代码结构优化 3.已知BUG修复) * Copyright (c) 2011, 梦幻神化 * http://www.bluesdream.com */ function waterfall(){ var wfArea = $("#waterfall"); //显示区域名称 var wfList = $(".picList"); //内容区域名称 var wfWidth = wfList.outerWidth(true); //获取内容区域实际宽度(含Margin值) var wfArr = new Array(); //创建数组,用来记录内容区域高度 var maxCol = Math.floor( $(window).width() / wfWidth ); //窗口的宽度除以内容区域宽度,并且向下取整(得出每行能放多少列) for(var i = 0; i < wfList.length; i++) { //根据内容区域数量进行循环 colHeight = wfList.eq(i).outerHeight(true); //获取每个内容区域的高度 if( i < maxCol ){ //如果i小于maxCol,那就说明是在一行里面(例如每行有4列,那就是4个为一组) wfArr[i] = colHeight; //把每组内容区域的高度,放入到数组中 wfList.eq(i).css("top",0); //第一行Li的默认Top值为0 wfList.eq(i).css("left",i * wfWidth); //每个列的Left值就是当前列数*内容区域宽度 }else{ minHeight = Math.min.apply(null,wfArr); //比较数值中的值,取得最小值(也就是每行中,最小高度) minCol = getArrayKey(wfArr, minHeight); //最小的值对应的指针 wfArr[minCol] += colHeight; //加上新高度后更新高度值 wfList.eq(i).css("top",minHeight); //先得到高度最小的Li,然后把接下来的li放到它的下面 wfList.eq(i).css("left",minCol * wfWidth); //第i个列的左坐标就是i*列的宽度 } wfList.eq(i).attr('id',"post_"+i); }; function getArrayKey(s, v) { //使用for in运算返回数组中某一值的对应项数(比如算出最小的高度值是数组里面的第几个) for( k in s ) { if( s[k] == v) { return k; } } }; var fwLastLayerT = parseInt(wfList.last().css("top")); //最后一个元素的Top值 var fwLastLayerH = wfList.last().outerHeight(true); //最后一个元素的高度 var wfAreaH = fwLastLayerT + fwLastLayerH + "px"; //显示区域的高度为 最后一个元素的Top值+自身高度 wfArea.css({ "width":wfWidth * maxCol,"height":wfAreaH }); //设置显示区域宽度和高度 } window.onload = function() { waterfall(); } //当页面加载完毕,执行函数 $(window).resize(function(){ //当窗口改变时,执行函数 waterfall(); }); });
HTML CODE:
</pre> <div class="info"> Ublue jQuery Waterfall By www.bluesdream.com</div> <div id="waterfall"> <div class="picList"><em class="shareIcon"></em> <div class="picThumbnail"><a href="#"><img src="images/img29.jpg" alt="" /></a></div> <div class="picDescription"> 图片介绍和描述 作者:Bluesdream.com</div> </div> <div class="picList"><em class="shareIcon"></em> <div class="picThumbnail"><a href="#"><img src="images/img30.jpg" alt="" /></a></div> <div class="picDescription"> 图片介绍和描述 作者:Bluesdream.com</div> </div> </div> <pre>
兼容:IE6-10、Firefox、Chrome、Safari、Opera
说明:Demo1 - 布局效果、Demo2 - 滚动无限加载
提示:Demo2滚动加载,是用JSON获取的数据,请在服务器环境下(IIS或Apache)测试。
提示:Demo3在Demo2的基础上增加瀑布流可显范围的修改提示和增加初次加载时的loading效果。
Virgil-Zhou 说:
我从楼主文章中获益匪浅,感谢楼主的无私,赞~~
October 6, 2015 2:23 pm
saber 说:
演示示例无效果呀!chrome ie10 都是如此
March 1, 2015 12:25 pm
木木 说:
强大,请问怎么做到加载了好多时候网页不卡呢,
August 30, 2013 11:40 am
蜗牛 说:
已点广告支持楼主
June 24, 2013 10:20 am
梦幻神化 说:
感谢(T_T)
June 24, 2013 10:50 am
Pingback 引用通告: Ublue jQuery Waterfall(瀑布流式布局) | wordpress公共资源库
lizhi 说:
为什么初始化,加载的时候,图片会有那个闪动的效果,能否做到,打开页面,出现正在加载~~的样子,还有,那个每行显示5个,可否改成每行4个一组,我调整了div woterfall的width但是还是不行的。能否固定住。
May 31, 2013 10:00 am
梦幻神化 说:
Q1:可以使用jquery的load,来判断图片是否加载成功。另外有个猥琐的办法,那是初始化图片的定位都是9999,定位到屏幕外面就OK。 Q2:因为我是计算的屏幕宽度,如果你想根据DIV的宽度,请把“var maxCol = ...”修改成“var maxCol = Math.floor( wfArea.width() / wfWidth );” 然后CSS控制“#waterfall”的宽度就行。
May 31, 2013 1:16 pm
lizhi 说:
第二个问题已经解决,但是第一个问题,希望给点代码实例,多谢。
May 31, 2013 3:55 pm
梦幻神化 说:
第一个问题的实例写好了,请看Demo3。
June 3, 2013 4:22 pm
soso辉 说:
还有一个问题,怎样才能让他停下来???
January 30, 2013 3:58 pm
梦幻神化 说:
设置个变量x,每滚动一次加1。滚动的时候只需要判断一下,例如:当x大于5(滚动5次),则不执行。
January 31, 2013 4:12 pm
soso辉 说:
为什么我下了你的demo,好像没效果啊,往下拉也不会自动加载???
January 30, 2013 3:41 pm
梦幻神化 说:
因为我用的JSON,要在服务器环境下(IIS或Apache)运行DEMO,否则像Crhome会提示不允许跨域访问,导致无法获取到数据。
January 31, 2013 4:07 pm
迷茫的凡人 说:
火狐,360
November 24, 2012 7:21 pm
梦幻神化 说:
你好,经过我的测试,在360(5.0)和火狐(17)中完全正常显示。方便的话,请提供下你的浏览器版本信息。你也可以尝试下用别的电脑访问看看,是不是你设置的问题。
November 25, 2012 2:49 pm
迷茫的凡人 说:
演示示例好像没效果啊
November 21, 2012 1:53 pm
梦幻神化 说:
嗯?你用的什么浏览器
November 22, 2012 11:33 pm