什么是瀑布流布局
瀑布流布局的每列宽度相同,图片高度各不相同,随着页面滚动条往下滚动,会不断加载数据块并附加至最后。
实现思路
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="./test.css">
<!-- <script src="./test.js"></script> -->
<script src="jquery-3.3.1.min.js"></script>
<script src="./test1.js"></script>
</head>
<body>
<div class="wrapper">
<div class="box">
<div class="pic"><img src="./img/1.png" alt="图片不存在"></div>
</div>
。。。。。。。// 此处很多个图片
<div class="box">
<div class="pic"><img src="./img/50.png" alt="图片不存在"></div>
</div>
</div>
</body>
</html>
css
*{
margin: 0;
padding: 0
}
.wrapper{
position: relative;
}
.wrapper .box{
position: absolute;
float: left;
padding: 0 10px 10px 10px;
}
.pic{
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
box-shadow: 0 0 5px #ccc;
}
.pic img{
width: 200px;
height: auto;
}
原生js
window.onload = function(){
/**
* 步骤:
* 1、页面加载时,就先加载出来
* 2、当窗口改变时,再次调用waterFull()
* 3、数据无限加载
*
* 思路:
* 1、计算窗口的宽度
* 2、每个盒子的宽度
* 3、列数为 步骤1/步骤2 向下取整
* 4、布满第一行,将他们的高度放入arr中
* 5、找到第一行最短的,值和index,将下一张图片放到最短的下边,更新arr,
* 6、再次查找最短的,放入下一张图片,并更新arr,一直到最后
* 7、计算滚动距离+一个屏幕的高度 与 最后一张图片距离顶端的高度 的差,以此来动态创建图片,
* 加入到最后,每次加一张图片就调用一次 waterFull()
*/
// 加载的时候先调用一次
var wrapper = document.getElementsByClassName('wrapper');
var box = document.getElementsByClassName('box');
waterFull();
function waterFull(){
// 获取可视区宽度
var pageWidth = getClient().width;
// 获取每张图片的宽度(总宽度)
var boxWidth = box[0].offsetWidth;
// 计算一共有多少列
var column = Math.floor(pageWidth / boxWidth);
// 定义数组,动态更新每一列的高度
var arr = [];
for(var i=0;i<box.length;i++){
// 第一行
if(i<column){
box[i].style.top = 0;
box[i].style.left = boxWidth*i + "px";
arr.push(box[i].offsetHeight);
// console.log(arr);
}else{
// 当是第二行,第三行。。。。
// 求最短的高度
var minHeight = Math.min.apply(null,arr);
// console.log(minHeight)
// 求高度最短的索引
var index = arr.indexOf(minHeight);
box[i].style.top = minHeight + "px";
box[i].style.left = index*boxWidth + "px";
// 更新arr
arr[index] = arr[index] + box[i].offsetHeight;
}
}
}
// 视口宽度改变时,重新计算
window.onresize = function(){
waterFull();
}
// 获取可视区的宽高
function getClient(){
return {
width : window.innerWidht || document.body.clientWidht || document.documentElement.clientWidth,
height : window.innerHeight || document.body.clientHeight || document.documentElement.clientHeight
}
}
// 获取滚动距离
function getScrollTop(){
return window.pageYOffset || document.body.scrollTop + document.documentElement.scrollTop;
}
// 模拟Ajax加载数据
window.onscroll = function(){
// 滚动距离和最后一个box的高度比较
var cha = getClient().height + getScrollTop() - (box[box.length-1].offsetTop);
var data = [
'./img/0.png',
'./img/1.png',
'./img/2.png',
'./img/3.png',
'./img/4.png',
'./img/5.png'
]
if(cha >= 0){
for(var i=0;i<data.length;i++){
var div = document.createElement('div');
div.className = 'box';
div.innerHTML = '<div class="pic"><img src="' + data[i] +'" alt="图片不存在"><div>';
wrapper[0].appendChild(div);
waterFull();
}
}
}
}
jQuery实现
window.onload = function(){
waterFull();
/*
$(function(){})与window.onload = function(){}的区别
$(function(){}) 是在页面渲染完之后调用的,这时候有一些图片资源等还没有下载完,就会出现图片的高度为0的情况
window.onload = function(){}:表示在页面渲染完,并且资源加载完之后再执行的,
所以如果要计算图片的高度,必须要等图片资源加载完,也就是要用第二种方式
*/
// 鼠标滚动事件
$(window).scroll(function(){
loadImg();
})
// 窗口大小改变事件
$(window).resize(function(){
waterFull();
})
}
// 瀑布流
function waterFull(){
var box = $('.box')
// 可视区的宽度
var pageWidth = $(window).width();
// console.log(pageWidth)
// 每个元素的宽度
var boxWidth = box.eq(0).outerWidth();
// console.log(boxWidth);
var column = Math.floor(pageWidth/boxWidth);
// 一共有多少列
// console.log(column);
var arr = [];
box.each(function(index, value){
if(index < column){
$(value).css({
top : 0,
left : index*boxWidth + "px"
})
arr.push($(value).outerHeight());
}else{
var minBox = Math.min.apply(null,arr);
var minBoxIndex = $.inArray(minBox, arr);
$(value).css({
"top" : minBox,
"left" : minBoxIndex*boxWidth + "px"
})
arr[minBoxIndex] += $(value).outerHeight();
}
})
}
// 无限加载数据
function loadImg(){
var all = $(window).height() + $(window).scrollTop();
var lastBoxHeight = $('.box').last().get(0).offsetTop;
if(all>lastBoxHeight){
var data = [
'./img/0.png',
'./img/1.png',
'./img/2.png',
'./img/3.png',
'./img/4.png',
'./img/5.png'
]
$.each(data,function(index,value){
var box = $("<div>").addClass("box").appendTo(".wrapper");
var content = $("<div>").addClass("pic").appendTo(box);
$("<img>").attr("src",data[index]).appendTo(content);
})
}
waterFull();
}
用到的知识点总结
1、$(function(){})
与window.onload = function(){}
的区别
$(function(){})
是在页面渲染完之后调用的,这时候有一些图片资源等还没有下载完,就会出现图片的高度为0的情况
window.onload = function(){}
:表示在页面渲染完,并且资源加载完之后再执行的
所以如果想要得到全部的图片高度,就要等图片资源全部加载完再进行,也就是用第二种方式
2、$.inArray(minBox, arr) 得到minBox在arr中的位置
网友评论