瀑布流的实现纯CSS实现Jquery实现
瀑布流的实现
注:本文部分图片自百度下载,如有侵权,联系删图。
首先,选择几张图片布局到HTML内容中。HTML如下所示。
<div class="wrapper"> <div class="item"><img src="img/1.jpg" height="auto"/></div> <div class="item"><img src="img/2.jpg" height="auto"/></div> <div class="item"><img src="img/3.jpg" height="auto"/></div> <div class="item"><img src="img/4.jpg" height="auto"/></div> <div class="item"><img src="img/5.jpg" height="auto"/></div> <div class="item"><img src="img/6.jpg" height="auto"/></div> <div class="item"><img src="img/7.jpg" height="auto"/></div> <div class="item"><img src="img/8.jpg" height="auto"/></div> <div class="item"><img src="img/9.jpg" height="auto"/></div> <div class="item"><img src="img/10.jpg" height="auto"/></div> <div class="item"><img src="img/11.jpg" height="auto"/></div> <div class="item"><img src="img/12.jpg" height="auto"/></div> <div class="item"><img src="img/13.jpg" height="auto"/></div> <div class="item"><img src="img/14.jpg" height="auto"/></div> <div class="item"><img src="img/15.jpg" height="auto"/></div> </div>
纯CSS实现
纯CSS实现较为简单,主要代码为设置列数和间距的两行。
/* 将边距设为0 */ *{ margin: 0; padding: 0; border: none; } .wrapper{ width: auto; height: auto; position: relative; margin: 0 auto; /* 设置列数和间距 */ column-count: 4; column-gap: 0; } .item{ position:relative; width: 100%; height: auto; box-sizing: border-box; padding: 2px; } .item img{ display: block; width: 100%; cursor: pointer; border-radius: 5px; } .item img:hover{ opacity: 0.8; }
Jquery实现
-
有bug 的写法
定义一个瀑布流方法:
function waterfall(element,child,padding) { var child = $(child) || $('.item'); var wrap = $(element) || $('.wrapper'); var padding = padding || 25; // 宽度,所有元素宽度一致 var itemW=$(".item").outerWidth(true); // 可容纳总列数 var colNum=Math.floor(wrap.outerWidth(true)/child.outerWidth(true)); console.log(colNum);//3 // 初始化第一列的top和left值 var posi=new Array(colNum); $.each(posi,(i)=>{ posi[i]=new Object(); posi[i].top = padding; posi[i].left = padding + i * itemW; }) // 每个元素所处列数 var eleCol=[]; //循环图片列表 child.each(function (i) { if ((i+1)% colNum == 0) { eleCol[i] = colNum; }else{ eleCol[i] = (i+1) % colNum; } var sub = eleCol[i]-1; var top = posi[sub].top+'px'; var left = posi[sub].left+'px'; // 设置每个元素的位置 $(this).css({"position":"absolute","top" :top,"left" : left}); // 每遍历完一次,重置top值 posi[sub].top += $(this).outerHeight(true); }) }
该方法原理图如图所示:
这是按照顺序,根据上行图片大小对定位加以调整的方式布局的。
但是,这种方法会造成空行。如图:
这是由于第一列某张图片过于大的缘故。
因此,在做瀑布流时,应该根据已布局好的元素的高度进行剩余元素的布局。就是说,比如第一行元素已经布局完成,第二行元素应该先选择第一行元素中,高度最小的那个元素所在列进行插入。这样,才能保证不会出现某一列太长或者某一列过短的现象。
-
根据以上分析,我们得到,实现瀑布流的核心其实是,找出图片高度最小的一列,并在此插入图片。
改进后的瀑布流方法:
function waterfall(element,child) { var child = $(child) || $('.item'); var wrap = $(element) || $('.wrapper'); // 宽度,所有元素宽度一致 var itemW=$(".item").outerWidth(true); // 可容纳总列数 var colNum=Math.floor(wrap.outerWidth(true)/child.outerWidth(true)); console.log(colNum);//3 // 定义列高度数组并初始化 var itemH = new Array(colNum); $.each(itemH,(i)=>{ itemH[i]=0; }) //循环图片列表 child.each(function (i) { // 定义最小高度和对应的index并初始化 var minHeight = itemH[0]; var minIndex = 0; console.log("最初最小高度为:"+minHeight+"下标为:"+minIndex); // 存储本次循环对象的高度 var thisH = $(this).outerHeight(true); $.each(itemH,(i)=>{ if (itemH[i] < minHeight) { minHeight = itemH[i]; minIndex = i; } console.log("比较后最小高度为:"+minHeight+"下标为:"+minIndex); }) var sub = minIndex; var top = minHeight; var left = minIndex * itemW; // 设置每个元素的位置 $(this).css({"position":"absolute","top" :top,"left" : left}); // 每遍历完一次,重置列高度值 itemH[sub] += thisH; console.log("itemH值:"+itemH[sub]); }) }
如图所示: