一、实现思路:
先在外层设置一个大的div,里面的小div设置绝对定位,小div的定位由jQuery代码动态排序。小盒子的排列顺序的思路如下:
先获取小div的宽度和文档窗口的宽度,计算一排可以存放几个div,大div的宽度等于小div的宽度(自身宽度+padding+margin)乘以 一排可以存放div的数量。给第一排盒子定位后,第二行的第一个接着第二排高度最小的下面,然后累加计算这列的高度。接下来的盒子都以此类推。
二、代码实现:
1.html部分
<div id="bodyBox">
<div class="fallBox fallBox1">
<div class="imgBox" data-index="1"><img src="images/1.png" alt=""></div>
<div class="title">
<h3>Tite 1</h3>
<p>info 1</p>
</div>
</div>
</div>
2.css部分:
* {
margin: 0;
padding: 0;
}
body {
background-color: #999;
}
#bodyBox {
height: 800px;
margin: 120px auto;
position: relative;
}
.fallBox {
width: 190px;
margin: 8px;
padding: 8px;
background-color: #fff;
float: left;
border-radius: 6px;
transition: .2s ease;
box-shadow: 0px 1px 3px #ccc;
display: flex;
flex-direction: column;
}
.fallBox:hover{
transform: translateY(-5px);
}
.title{
margin: 5px 0;
height: 80px;
}
.title p{
font-size: 14px;
color: #ccc;
margin-top: 20px;
}
.imgBox{
width: 100%;
}
.imgBox img{
width: 100%;
height: 100%;
}
3.jq部分:
1)瀑布流布局原理:
确定一排存放几个盒子,第二排第一个接着在第一个高度最小的那个下面,以此类推。
/*1.计算一排可以放几个*/
//获取窗口、小盒子的宽度
var clientWitdh = $(window).width();
var boxWitdh = $('.fallBox').outerWidth(true);
//盒子个数
var boxNum = Math.floor(clientWitdh / boxWitdh);
$('#bodyBox').css({
width: boxNum * boxWitdh + 'px',
});
/*2.给盒子排序:
遍历盒子,排完第一排后,第二排第一个要加在第一排高度最短的后面,然后累加这列的高度;
*/
var arr_height = [];//存放第一行盒子的高
$.each($('.fallBox'), function (i, ele) {
if (boxNum > i) {
arr_height[i] = $(this).outerHeight(true);
$(this).css({
position: 'absolute',
left: boxWitdh * i + 'px',
top: 0
});
}
else {//除第一行的盒子
//获取第一行最短高度的盒子和索引
var minHeight = Math.min.apply(null, arr_height);
var index = arr_height.indexOf(minHeight);
$(this).css({
position: 'absolute',
left: boxWitdh * index + 'px',
top: minHeight + 'px'
})
//更新盒子最短高度
arr_height[index] += $(this).outerHeight(true);
}
})
2)动态加载:
初始化节点,让盒子充满可视的窗口:
var tem = 0;
//初始添加十个盒子节点
for (let i = 1; i <= 10; i++) {
fun_add(i);
tem = i;
}
确定加载的节点:
$(window).on('scroll',function(){
//获取最后一个盒子距文档上方的高度
var lastBoxTop = $('.fallBox:last').offset().top;
//获取文档被卷去的头部
var scrollHei = $(document).scrollTop();
//获取文档的高度
var documHei = $(document).height();
console.log(lastBoxTop);
if(scrollHei+documHei > lastBoxTop){
//加载节点
fun_add(++tem);
}
//重新布局
relayout();
添加节点:
//添加子盒子节点
var div = $('<div></div>').addClass('fallBox').css('height', Math.ceil(Math.random() * (300 - 150 + 1) + 150)).appendTo($('#bodyBox'));
div.attr('data-index',i);
//添加图片盒子节点
var img = $('<div></div>').addClass('imgBox').css('height',div.height()-$('.title').outerHeight(true)).appendTo(div);
img.html('<img src="images/' + Math.ceil(Math.random() * 4) + '.png" alt="">');
//添加文字盒子节点
var tit = $('<div></div>').addClass('title').appendTo(div);
tit.html('<div class="title"><h3>Tite '+div.attr('data-index')+'</h3><p>info '+div.attr('data-index')+'</p></div>');
4.jQuery完整代码:
var tem = 0;
$(function () {
//初始添加十个盒子节点
for (let i = 2; i < 10; i++) {
fun_add(i);
tem = i;
}
//初始布局
relayout();
$(window).on('resize', function () {//窗口大小改变事件,使瀑布流排列能随窗口大小改变而改变
//重新布局
relayout();
})
//动态加载盒子
addBox();
})
/*添加节点*/
function fun_add(i){
//添加子盒子节点
var div = $('<div></div>').addClass('fallBox').css('height', Math.ceil(Math.random() * (300 - 150 + 1) + 150)).appendTo($('#bodyBox'));
div.attr('data-index',i);
//添加图片盒子节点
var img = $('<div></div>').addClass('imgBox').css('height',div.height()-$('.title').outerHeight(true)).appendTo(div);
img.html('<img src="images/' + Math.ceil(Math.random() * 4) + '.png" alt="">');
//添加文字盒子节点
var tit = $('<div></div>').addClass('title').appendTo(div);
tit.html('<div class="title"><h3>Tite '+div.attr('data-index')+'</h3><p>info '+div.attr('data-index')+'</p></div>');
}
/*动态加载盒子*/
function addBox(){
$(window).on('scroll',function(){
var lastBoxTop = $('.fallBox:last').offset().top;
var scrollHei = $(document).scrollTop();
var documHei = $(document).height();
console.log(lastBoxTop);
if(scrollHei+documHei > lastBoxTop){
fun_add(++tem);
}
//重新布局
relayout();
})
}
/*瀑布流布局*/
function relayout() {
/*1.计算一排可以放几个*/
//获取窗口、小盒子的宽度
var clientWitdh = $(window).width();
var boxWitdh = $('.fallBox').outerWidth(true);
//盒子个数
var boxNum = Math.floor(clientWitdh / boxWitdh);
$('#bodyBox').css({
width: boxNum * boxWitdh + 'px',
});
/*2.给盒子排序:
遍历盒子,排完第一排后,第二排第一个要加在第一排高度最短的后面,然后累加这列的高度;
*/
var arr_height = [];//存放第一行盒子的高
$.each($('.fallBox'), function (i, ele) {
if (boxNum > i) {
arr_height[i] = $(this).outerHeight(true);
$(this).css({
position: 'absolute',
left: boxWitdh * i + 'px',
top: 0
});
}
else {//除第一行的盒子
//获取第一行最短高度的盒子和索引
var minHeight = Math.min.apply(null, arr_height);
var index = arr_height.indexOf(minHeight);
$(this).css({
position: 'absolute',
left: boxWitdh * index + 'px',
top: minHeight + 'px'
})
//更新盒子最短高度
arr_height[index] += $(this).outerHeight(true);
}
})
}
5.效果图: