瀑布流布局的特点:各盒子等宽不等高
大概效果如下:
分析
-
通过定位布局
-
先确定在浏览器显示区域内,一行能放多少列图片
- 获取页面的宽度pageWidth(做兼容)
- 图片盒子宽度itemWidth
- 间隙gap
- 列数:column=pageWidth/(itemWidth+gap)
-
先排第一行
- 当盒子索引小于列数column的时候,就排在第一行
- 确定在第一行后,动态设置left的值,top值为0
- left=i*(itemWidth+gap)
-
第一行排好之后,因为第二行需要考虑top值,将第一行所有盒子的高度存入数组arr,便于确定第二行元素的排列
-
获取图片高度的时候要注意需要等页面数据加载完成之后再获取高度,放在onload函数中去实现
-
arr[h1,h2,h3…]
-
-
排列第二行
- 找出第一行高度最小(min)的盒子,第二行第一个盒子就排在其下方
- left相同,top值为min+gap
- 记录当前高度最小盒子的索引index
- 更新arr[index]的值:arr[index]=min+gap+items[index].offsetHeight(原来的高度加上间隙再加上其下第二行元素的高度)
-
触发resize事件
- 实时改变pageWidth的宽度,得到一个响应式效果
-
注意:
- offsetHeight没有单位,style.left含有单位
- 更新高度arr数组
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div{
width: 60px;
position: absolute;
}
.blueviolet{
height: 190px;
background-color: blueviolet;
}
.lightskyblue{
height: 200px;
background-color: lightskyblue;
}
.aqua{
height: 250px;
background-color: aqua;
}
.pink{
height: 150px;
background-color: pink;
}
.greenyellow{
height: 90px;
background-color: greenyellow;
}
</style>
</head>
<body>
<div class="blueviolet"></div>
<div class="lightskyblue"></div>
<div class="aqua"></div>
<div class="pink"></div>
<div class="greenyellow"></div>
<div class="aqua"></div>
<div class="pink"></div>
<div class="lightskyblue"></div>
<div class="aqua"></div>
<div class="blueviolet"></div>
<div class="lightskyblue"></div>
<div class="pink"></div>
<div class="greenyellow"></div>
<div class="aqua"></div>
<div class="pink"></div>
<div class="greenyellow"></div>
<div class="aqua"></div>
<div class="pink"></div>
<div class="lightskyblue"></div>
<div class="aqua"></div>
<div class="lightskyblue"></div>
<div class="aqua"></div>
<div class="blueviolet"></div>
<div class="lightskyblue"></div>
<div class="pink"></div>
<script>
window.onload=function(){
WaterFall();
}
window.onresize=function(){
WaterFall();
}
//做兼容
function getClient(){
return {
width:window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth,
height:window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight
}
}
function WaterFall(){
var items=document.querySelectorAll('div');
var pageWidth=getClient().width;
var itemWidth=items[0].offsetWidth;
var gap=10;
var column=Math.floor(pageWidth/(itemWidth+gap));
var arr=[];//存储第一行盒子高度
for(var i=0;i<items.length;i++){
if(i<column){
//排在第一列
items[i].style.top=0;
items[i].style.left=i*(itemWidth+gap)+'px';
//存储第一行盒子高度
arr.push(items[i].offsetHeight);
}else{
//找到第一行高度最小的并且记录其索引
var min=arr[0];
var index=0;
for(var j=0;j<arr.length;j++){
if(arr[j]<min){
min=arr[j];
index=j;
}
}
//设置下一行第一个元素的位置
items[i].style.top=min+gap+'px';
items[i].style.left=items[index].style.left;
//更新高度
arr[index]=min+gap+items[i].offsetHeight;
}
}
}
</script>
</body>
</html>
效果:
改变页面大小后: