什么是瀑布流布局
瀑布流布局的每列宽度相同,图片高度各不相同,随着页面滚动条往下滚动,会不断加载数据块并附加至最后。
实现思路
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 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦