很早以前我就想自己学写一下瀑布流布局,可是由于懒神来找我聊天咯,所以推迟咯很久直到今天我才来写瀑布流布局。由于鄙人的js还有很大的提升空间,所以我是先看咯一下那些大神的具体讲解和分析,然后才开始着手写的,收获那是杠杠的。
1、大家都知道要想实现瀑布流,就必须规定每一个区块的宽度要一致
2、确定每一排要放置多少列(容器的宽度/区块的宽度 然后用Math.floor向下取整数)
3、容器第一排放置的所有区块具体顶部都是一样的距离(距离左面的距离就是他的索引*区块的offsetWidth)
4、然后寻找高度最低的区块位置,然后下面接着开始放置区块
5、除了第一排的距离顶部是相同的,第二排开始区块的绝对定位,top值为它上i个区块的高度+margin值,
具体的效果图如下:
具体代码如下所示(里面包括咯具体的注释说明):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>瀑布流布局</title>
</head>
<style>
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td {padding: 0;margin: 0;}
li{ list-style: none; width: auto;}
.wrap{ width: 1140px; height: 2000px;margin:0 auto; position: relative;}
.wrap li{ float: left; position: absolute; top:0; left:0; text-align: center;}
.wrap li img{ display: block;}
h2{ color: #ff0000; text-align: center; line-height: 50px;}
</style>
<body>
<h2>下面是我写的一个瀑布流布局的页面</h2>
<div class="wrap" id="wrap">
<ul>
<li>
<img src="imgs/1.jpg" alt="" />
<p>图标标题</p>
</li>
<li>
<img src="imgs/2.jpg" alt="" />
<p>图标标题</p>
</li>
<li>
<img src="imgs/3.jpg" alt="" />
<p>图标标题</p>
</li>
<li>
<img src="imgs/4.jpg" alt="" />
<p>图标标题</p>
</li>
<li>
<img src="imgs/5.jpg" alt="" />
<p>图标标题</p>
</li>
<li>
<img src="imgs/6.jpg" alt="" />
<p>图标标题</p>
</li>
<li>
<img src="imgs/7.jpg" alt="" />
<p>图标标题</p>
</li>
<li>
<img src="imgs/8.jpg" alt="" />
<p>图标标题</p>
</li>
<li>
<img src="imgs/9.jpg" alt="" />
<p>图标标题</p>
</li>
<li>
<img src="imgs/6.jpg" alt="" />
<p>图标标题</p>
</li>
<li>
<img src="imgs/7.jpg" alt="" />
<p>图标标题</p>
</li>
<li>
<img src="imgs/8.jpg" alt="" />
<p>图标标题</p>
</li>
<li>
<img src="imgs/9.jpg" alt="" />
<p>图标标题</p>
</li>
<li>
<img src="imgs/10.jpg" alt="" />
<p>图标标题</p>
</li>
<li>
<img src="imgs/1.jpg" alt="" />
<p>图标标题</p>
</li>
<li>
<img src="imgs/2.jpg" alt="" />
<p>图标标题</p>
</li>
<li>
<img src="imgs/3.jpg" alt="" />
<p>图标标题</p>
</li>
<li>
<img src="imgs/4.jpg" alt="" />
<p>图标标题</p>
</li>
<li>
<img src="imgs/9.jpg" alt="" />
<p>图标标题</p>
</li>
<li>
<img src="imgs/6.jpg" alt="" />
<p>图标标题</p>
</li>
<li>
<img src="imgs/7.jpg" alt="" />
<p>图标标题</p>
</li>
<li>
<img src="imgs/8.jpg" alt="" />
<p>图标标题</p>
</li>
<li>
<img src="imgs/9.jpg" alt="" />
<p>图标标题</p>
</li>
<li>
<img src="imgs/10.jpg" alt="" />
<p>图标标题</p>
</li>
<li>
<img src="imgs/6.jpg" alt="" />
<p>图标标题</p>
</li>
<li>
<img src="imgs/8.jpg" alt="" />
<p>图标标题</p>
</li>
</ul>
</div>
</body>
<script src="http://libs.baidu.com/jquery/1.10.2/jquery.min.js"></script>
<script>
var margin = 10,//设置区块的margin值
li = $("li"),//获取区块数组
li_W = li[0].offsetWidth + margin;//获取并设置区块的宽度(如果区块设置咯边框,那么这个里面就包含咯边框)
console.log(li_W);
function waterfall(){
var h=[],//定义一个数组,用来装所以的li的高度值的一个数组
wrap = document.getElementById("wrap"),//获取容器id
wrap_W = wrap.offsetWidth,//获取容器的宽度
n = Math.floor(wrap_W/li_W);//设置容器一行能发几个区块
for( var i = 0; i<li.length;i++){
li_H = li[i].offsetHeight;//取得每个li的高度
if(i < n){//这里的n代表的是一行能放几个区块,如果小于n,就说明是位置在第一排
h[i] = li_H;//把每个区块的高度放在一个数组里面(记住这里的这句一定要写在小于 n 的if里面 ,想看别的效果你可以试一下放在外面是什么样式的)
li.eq(i).css({
"top":0,
"left":i*li_W
});
}else{
min_H =Math.min.apply(null,h);//取得数组中的最小值,区块中高度值最小的那个
minkey = getMinnumer(min_H,h); //最小的值对应的指针
h[minkey]+= li_H+margin ;//加上新高度后更新高度值
li.eq(i).css({
"top":min_H+margin,
"left":minkey * li_W
});
}
}
}
//取集合中最小的一个数
function getMinnumer(min,box){//min代表的是最小的那个数,box代表一个集合
for(num in box){
if(box[num] == min){
return num;
}
}
}
/*这里一定要用onload,因为图片不加载完就不知道高度值*/
window.onload = function() {
waterfall();
};
/*浏览器窗口改变时也运行函数*/
window.onresize = function() {
waterfall();
};
</script>
</html>
如果里面还可以修改的更完美的话,请大神赐教,谢谢!