什么是瀑布流布局
瀑布流布局的每列宽度相同,图片高度各不相同,随着页面滚动条往下滚动,会不断加载数据块并附加至最后。
实现思路
html
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Document</title> <link rel="stylesheet" href="./test.css"> <!-- <script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="./test.js"></script> --> <script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="jquery-3.3.1.min.js"></script> <script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="./test1.js"></script></head><body> <div class="wrapper"> <div class="box"> <div class="pic"><img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="./img/1.png" alt="图片不存在"></div> </div> 。。。。。。。// 此处很多个图片 <div class="box"> <div class="pic"><img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="./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. = 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 class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="' + data[i] +'" alt="图片不存在"><div>';
wrapper[0].appendChild(div);
waterFull();
}
}
}
}jQuery实现
window. = function(){
waterFull(); /*
$(function(){})与window. = function(){}的区别
$(function(){}) 是在页面渲染完之后调用的,这时候有一些图片资源等还没有下载完,就会出现图片的高度为0的情况
window. = 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. = function(){}的区别$(function(){})是在页面渲染完之后调用的,这时候有一些图片资源等还没有下载完,就会出现图片的高度为0的情况window. = function(){}:表示在页面渲染完,并且资源加载完之后再执行的
所以如果想要得到全部的图片高度,就要等图片资源全部加载完再进行,也就是用第二种方式
2、$.inArray(minBox, arr) 得到minBox在arr中的位置
作者:椰果粒
链接:https://www.jianshu.com/p/272c4596c58e
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦