瀑布流布局
在淘宝,蘑菇街等网站上我们经常可以看到瀑布流布局,而瀑布流布局的始祖便是www.pinterest.com,如下所示:
瀑布流,又称瀑布流式布局。是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部。最早采用此布局的网站是Pinterest,逐渐在国内流行开来。国内大多数清新站网站为这类风格。
实现这种布局实际上并不困难,这里不讲解和后台交互的部分。
html代码如下:
<div id="waterfull">
<div class="box">
<div class="box_image"><img src="waterfull_images/1.jpg" alt=""></div>
</div>
<div class="box">
<div class="box_image"><img src="waterfull_images/2.jpg" alt=""></div>
</div>
<div class="box">
<div class="box_image"><img src="waterfull_images/3.jpg" alt=""></div>
</div>
<div class="box">
<div class="box_image"><img src="waterfull_images/4.jpg" alt=""></div>
</div>
<div class="box">
<div class="box_image"><img src="waterfull_images/5.jpg" alt=""></div>
</div>
<div class="box">
<div class="box_image"><img src="waterfull_images/6.jpg" alt=""></div>
</div>
<div class="box">
<div class="box_image"><img src="waterfull_images/7.gif" alt=""></div>
</div>
<div class="box">
<div class="box_image"><img src="waterfull_images/8.jpg" alt=""></div>
</div>
<div class="box">
<div class="box_image"><img src="waterfull_images/9.jpg" alt=""></div>
</div>
<div class="box">
<div class="box_image"><img src="waterfull_images/10.jpg" alt=""></div>
</div>
</div>
这里,我放了10张图片,当然可以根据需要放置任意多张的图片。最外层id为waterfull的div是用于包裹整个瀑布流布局的。而class为box的div是用于分隔开每一张图片的。class为box_image的div是用于在css中描述与修饰图片的。
下面是css部分的代码:
#waterfull{width: 1200px;height: auto;position: relative;}
.box{float:left; padding: 5px;}
.box_image{padding:5px;border:1px solid #ccc; border-radius: 5px; box-shadow: 5px 5px 8px #ccc}
#waterfull img{width: 278px;height: auto;}
其中waterfull的宽度最好是给定的,高度我们可以通过放置图片的高度来把它撑开。至于position:relative,是为了用于每一张图片的绝对定位时以waterfull为定位的基准。紧接着,我们让图片浮动起来,这样就可以从左到右,从上到下的排列了。对于紧邻图片的div,我们可以设置一个边框,通过box-shadow做出阴影的效果。而img的宽度设置是十分必要的,可以看出Pinterest中就是这样。
下面是javascript代码:
window.onload=function(){
images_location("waterfull","box");
function images_location(Parent,Children){
var parent=document.getElementById(Parent);//获取id为waterfull的元素
var children=getChildElement(parent,Children);//通过一个封装函数来获取上述获取到的元素的所有符合条件的子元素,获得一个数组
var imageWidth=children[0].offsetWidth;//因为在css中已经设定了固定宽度,所以只需要第一张图片的宽度。
var cols=Math.floor(1250/imageWidth);获取在固定宽度的情况下可以放下的列数。当然这里可以不用固定宽度,而使用用户浏览器的宽度document.documentElement.clientWidth。
var hArr=[];
for(var i=0;i<children.length;i++){
if(i<cols){
hArr.push(children[i].offsetHeight);//将第一列中的图片高度数据存到hArr数组中
}else{
var minH=Math.min.apply(null,hArr);//又有Math.min方法的参数必须是一个一个的数,故这里使用apply方法传入数组求得最小的高度
var index=getMinhIndex(hArr,minH);//封装一个函数获得最小高度的图片所在列的索引
children[i].style.position="absolute";//使用绝对定位
children[i].style.top=minH+"px";//注意:这里一定要有px这个单位,否则将会出错
children[i].style.left=imageWidth*index+"px";//即left的值
hArr[index]+=children[i].offsetHeight;//将刚添加的那一列的offsetHeight值更新
}
}
}
function getChildElement(Parent,Children){
var childrenArr=[];
var allChildren=Parent.getElementsByTagName("*");
for(var i=0;i<allChildren.length;i++){
if(allChildren[i].className==Children){//注意:原生JavaScript中对于元素由className这个属性,即获取类名。
childrenArr.push(allChildren[i]);
}
}
return childrenArr;
}
function getMinhIndex(arr,val){
for(var i in arr){ //遍历arr数组中的每一个元素,其中i表示各元素的索引
if(arr[i]==val){
return i;
}
}
}
}
好了,瀑布流就大功告成了,是不是很简单呢。下面看看最终的效果图: