
这就是PC端比较常见的瀑布流布局方式,接下来我们审查下元素看看百度图片里面是如何布局:

可以看到,它里面实际是若干个等宽的列容器,通过计算将图片push到不同的容器里。而本文介绍的展示方法是通过定位的方式,虽然最后布局展示的方式不同,但之前的算法都比较类似。
动手
首先我们将如下样式的若干个单元写进body中,并将“box”向左浮动:
<div class="box"> <img class="img" src="./resource/images/1.jpg" /> <div class="desc">Description</div></div><div class="box"> <img class="img" src="./resource/images/2.jpg" /> <div class="desc">Description</div></div><div class="box"> <img class="img" src="./resource/images/3.jpg" /> <div class="desc">Description</div></div>得到如下效果:

接下来:
var boxArr = $(".box"), num = Math.floor(document.body.clientWidth / boxArr.eq(0).outerWidth(true)), columnHeightArr = [];columnHeightArr.length = num;boxArr.each(function(index, item) { if (index < num) { columnHeightArr[index] = $(item).outerHeight(true); } else { var minHeight = Math.min.apply(null, columnHeightArr), minHeightIndex = $.inArray(minHeight,columnHeightArr); $(item).css({ position: "absolute", top: minHeight, left: boxArr.eq(minHeightIndex).position().left }); }}); 以上代码大意为:
可以看到虽然摆对了地方但是所有的图片都放在同一个地方了,这是因为我们需要在摆放一张图片后就要增加该列的高度:
var boxArr = $(".box"), num = Math.floor(document.body.clientWidth / boxArr.eq(0).outerWidth(true)), columnHeightArr = [];columnHeightArr.length = num;boxArr.each(function(index, item) { if (index < num) { columnHeightArr[index] = $(item).outerHeight(true); } else { var minHeight = Math.min.apply(null, columnHeightArr), minHeightIndex = $.inArray(minHeight, columnHeightArr); $(item).css({ position: "absolute", top: minHeight, left: boxArr.eq(minHeightIndex).position().left }); columnHeightArr[minHeightIndex] += $(item).outerHeight(true); }}); 结果正确: 
.box { width: 50%; height: 0; padding-bottom: 100%;}不设置高度,而是用padding“挤”出元素高度,而padding的百分比值都是基于父级容器的宽度。padding需要挤多少呢?就是宽度乘以高宽比(width和padding值均为百分比值),这就是我们为什么需要获得图片尺寸的原因。
可以看到在chrome手机模拟器中ipone4和肾6Plus的显示效果是完全一样的。在手机页面中宽是固定的,而高会随着页面内容的多少而变化,这个技巧利用元素padding百分比的值其实是基于其父级容器的宽,将高的值巧妙的转化成与宽相关。
说到现在可能有人终于忍不住要问了,讲了这么多和瀑布流有什么关系!简单就是一句话,我们要抛弃 img 标签,而采用背景图的方式。为了使用背景图,就得保持元素的比例永远与图片保持一致。
通过这种方式,可以不用判断图片都加载完毕,直接产生一些与图片同比例的div,再为其设置背景图,如下:

这里比如最外层的box宽度为220px,里面的img元素宽度就可以为100%,高度就可以通过padding挤出了。
懒加载
使用背景图的方式还有好处那就是可以比较方便的实现懒加载。那什么是懒加载呢?就是当元素在我们的视野中时才展示图片,滚动时屏幕下方的图片并不展示,这可以很好的增加加载速度提升体验。
首先我们给最外层的box增加一个box-item类名(之后有用),将图片url并不设置给backgroundImage属性,而是赋给一个自定义属性:data-src。
<div class="box box-item"> <div class="img" data-src="./resource/images/1.jpg"></div> <div class="desc">Description</div></div>接下来我们编写懒加载函数:
function lazyLoad() { var boxArr = $(".box-item"); boxArr.each(function(index, item) { var viewTop = $(item).offset().top - $(window).scrollTop(), imgObj = $(item).find(".img"); if ((viewTop < $(window).height()) && (($(item).offset().top + $(item).outerHeight(true)) > $(window).scrollTop())) { imgObj.css("backgroundImage","url("+imgObj.attr("data-src")+")").removeClass("data-src"); $(item).removeClass("box-item"); } })}首先我们获取所有拥有 .box-item 类名的元素,遍历。viewTop 为图片相对于浏览器窗口的相对高度,类似于position:fixed感觉。function scrollLoad() { var viewHeight = $(window).scrollTop() + $(window).height(), minHeight = Math.min.apply(null, columnHeightArr); if (viewHeight >= minHeight) { //loadMore... }}滚动加载也是在window的滚动事件中进行监听,可以与懒加载一起进行:$(window).scroll(function() { scrollLoad(); lazyLoad(); });说完了PC端,我们来说下手机端。其实原理是一样的,只是从多列变成固定的两列了。var boxArr = $(".box"), columnHeightArr = [];columnHeightArr.length = 2;boxArr.each(function(index, item) { if (index < 2) { columnHeightArr[index] = $(item).outerHeight(true); } else { var minHeight = Math.min.apply(null, columnHeightArr), minHeightIndex = $.inArray(minHeight, columnHeightArr); $(item).css({ position: "absolute", top: minHeight, left: boxArr.eq(minHeightIndex).position().left }); columnHeightArr[minHeightIndex] += $(item).outerHeight(true); }});不同的是为了适应不同屏幕的手机,最外层的box容器宽度和边距要设置成百分比的形式。
最后有一点要注意,因为我们没有像百度一样用一个个列盒子去装,而是用定位的方式。导致的问题是图片元素的父级没法自适应高度,如果你有相关的需求我们可以计算出所有列中最长的长度,并将这个值赋值给父容器的min-height属性:
$("body").css("minHeight",Math.max.apply(null, columnHeightArr));
整理下完整的代码,瀑布流的全套服务就到这了
var dataArr = [ {picUrl:"./resource/images/1.jpg",width:522,height:783}, {picUrl:"./resource/images/2.jpg",width:550,height:786}, {picUrl:"./resource/images/3.jpg",width:535,height:800}, {picUrl:"./resource/images/4.jpg",width:578,height:504}, {picUrl:"./resource/images/5.jpg",width:1440,height:900} ]; $.each(dataArr, function(index, item) { $("body").append("<div class="box box-item">" +"<div class="img" style="height:0;padding-bottom:"+cRate(item) * 100 + "%"+"" data-src=""+item.picUrl+""></div>" +"<div class="desc">Description</div>" +"</div>"); }); var boxArr = $(".box"), num = Math.floor(document.body.clientWidth / boxArr.eq(0).outerWidth(true)), columnHeightArr = []; columnHeightArr.length = num;arrangement(); $("body").css("minHeight",Math.max.apply(null, columnHeightArr)); lazyLoad(); function arrangement() { boxArr.each(function(index, item) { if (index < num) { columnHeightArr[index] = $(item).outerHeight(true); } else { var minHeight = Math.min.apply(null, columnHeightArr),minHeightIndex = $.inArray(minHeight, columnHeightArr); $(item).css({position: "absolute",top: minHeight,left: boxArr.eq(minHeightIndex).position().left }); columnHeightArr[minHeightIndex] += $(item).outerHeight(true); } }); } function lazyLoad() { var boxArr = $(".box-item"); boxArr.each(function(index, item) { var viewTop = $(item).offset().top - $(window).scrollTop(), imgObj = $(item).find(".img"); if ((viewTop < $(window).height()) && ($(item).offset().top + $(item).outerHeight(true) > $(window).scrollTop())) {// console.log($(item).attr("data-src")); imgObj.css("backgroundImage","url("+imgObj.attr("data-src")+")").removeClass("data-src"); $(item).removeClass("box-item"); } }) } function cRate(obj) { return obj.height / obj.width; } function scrollLoad() { var viewHeight = $(window).scrollTop() + $(window).height(), minHeight = Math.min.apply(null, columnHeightArr); if (viewHeight >= minHeight) { //loadMore... } } $(window).scroll(function() { lazyLoad(); scrollLoad(); });以上就是为大家分享的关于jQuery瀑布流布局,内容很丰富,需要大家一点点的理解消化,真正的做到学以致用,希望能够帮助到大家。