很多时候项目中图片的排布都是**以div定宽高包裹,img设置100%**实现。这样在只有少量图片的网站上有奇效——样式简单、布局便捷。 以前一直为发现了这一方法而“沾沾自喜”,但近来浏览了【百度图片】网页 。。。 莫名的就想到了【瀑布流布局】
开篇
何为瀑布流布局
形似瀑布排列,通常来说高度不固定而 宽度固定(以达到页面resize
排列改变的效果),下一排图片紧接着上一排放,如下:
要达到这种效果,首先我们要分析图片的排列特点:
上面说“下一行紧贴着上一行排列”,我们顺着“上一行”网上找,发现了一个特殊的地方——第一行。
我们很容易知道,第一行就是整个【(图片)瀑布流】的基础/参照。
有了这个,我们又能得到——除了第一行,其余的图片都要进行position:absolute;
处理。也就是说,整个区域内,只有第一行图片在文档流内:知道这一点很重要。
我们继续往下看,假如说现在我们有这样一行:
并且设定了其高度分别为100、120、200,宽度为200,那么下一行应该这样排列:
我们可以发现一个规律:
position: absolute;
left: i*图片宽度
top: 最小高度
如何求这个【最小高度】值呢?这可是解决的关键! 我们不妨将数据都放到数组中:
数组 [100,120,200]
配合【列数】,进行求解。
大致思路如此,让我们一起来看下代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>试验图片动态响应排列</title>
<script src="../js/jquery.min.js"></script>
<script src="../js/mxc.js"></script>
<style>
/* overflow:hidden;在此利用了BFC原理,使得大div边框能包裹所有元素 */
.mxc{width: 90%;border: 1px solid red;margin-left: 5%;overflow: hidden;}
.mxc img{float: left;width: 90px;height: 60px;}
</style>
</head>
<body>
<div class="mxc">
<img src="../Web项目实战/app/src/components/inputBar/img/emoji/pngs/small_red_triangle_down.png" alt="" />
<img src="../Web项目实战/app/src/components/inputBar/img/emoji/pngs/smile.png" alt="" />
<img src="../Web项目实战/app/src/components/inputBar/img/emoji/pngs/smile_cat.png" alt="" />
<img src="../Web项目实战/app/src/components/inputBar/img/emoji/pngs/smiley.png" alt="">
<img src="../Web项目实战/app/src/components/inputBar/img/emoji/pngs/smiley_cat.png" alt="">
<img src="../Web项目实战/app/src/components/inputBar/img/emoji/pngs/smiling_imp.png" alt="">
<img src="../Web项目实战/app/src/components/inputBar/img/emoji/pngs/smirk.png" alt="">
<img src="../Web项目实战/app/src/components/inputBar/img/emoji/pngs/smoking.png" alt="">
<img src="../Web项目实战/app/src/components/inputBar/img/emoji/pngs/small_red_triangle_down.png" alt="" />
<img src="../Web项目实战/app/src/components/inputBar/img/emoji/pngs/smiliie.png" alt="" />
<img src="../Web项目实战/app/src/components/inputBar/img/emoji/pngs/smile_catbb.png" alt="" />
<img src="../Web项目实战/app/src/components/inputBar/img/emoji/pngs/smileycc.png" alt="">
<img src="../Web项目实战/app/src/components/inputBar/img/emoji/pngs/smiley_catdd.png" alt="">
<img src="../Web项目实战/app/src/components/inputBar/img/emoji/pngs/smiling_impee.png" alt="">
<img src="../Web项目实战/app/src/components/inputBar/img/emoji/pngs/smiggrk.png" alt="">
<img src="../Web项目实战/app/src/components/inputBar/img/emoji/pngs/smokinghh.png" alt="">
</div>
</body>
</html>
因为这里用的jQuery,js文件中应该这样写:
$(function(){ //这是$(document).ready(function(){})的缩写
})
在正式开始处理图片之前,我们首先要获取到需要的信息——宽度 & 列数:
var allBox=$(".mxc img") //-- 如果每个图片外有小div包裹,这里改变
var boxWidth=allBox.outerWidth(); //一个img的宽度
var screenWidth=$(window).width(); //可见区域的宽
var cols=parseInt(screenWidth/boxWidth); //列数
var heightArr=[]; //获取高度的数组
然后去处理图片:
$.each(allBox,function(index,item){
var boxHeight=item.outerHeight(); //每张图片高度 -- 如果每个图片外有小div包裹,这里item换成$(item)即可
if(index < cols){
heightArr[index]=boxHeight;
}else{
item.css({
position:'absolute',
left:i*boxWidth
top:'最小高度'
})
}
})
这个 i 是什么?=> 最小高度的索引。
那如何求出所谓“最小的i”?
我们首先想到的几乎一定是【遍历数组】了。
有没有人会想到Math.min()
函数呢?这可是个好工具:他能简便的求出字符串中的最小值。
字符串?对了,我们得到的是数组!
没关系,我们不是还有apply的嘛 —— apply,其主要作用是将第二个参数代入第一个参数中运算(因为第一个参数通常是this,所以常用于this指针的重定向)
apply函数的第二个参数是数组
所以上面代码中else部分可以改为下面这样:
var minBoxHeight=Math.min.apply(Math.min,heightArr);
var minHeightIndex=$.inArray(minBoxHeight,heightArr); //jQuery中的求索引函数
item.css({ // -- 如果每个图片外有小div包裹,这里item换成$(item)即可
position:'absolute',
left:minHeightIndex*boxWidth+'px',
top:minBoxHeight+'px'
})
//改变了宽高,我们要将“最小高度”进行更新
heightArr[minHeightIndex]+=boxHeight;
Tip: outerWidth():不包含margin(jQuery-API,相当于js中的offsetWidth) innerWidth():不包含margin、border width():不包含padding、margin、border
这样,功能上算是完成了。但是当我们打开页面,会发现每一次刷新都有可能有的地方会出现高度上的错误。 此时笔者的内心是懵逼的...
在笔者将代码从上往下再从下往上看了一遍又一遍时,突然想到了页面加载时图片后于文档流加载
啊呀,把这个忘了:我们应当把开头的$(function(){})
换成:
$(window).on('load',function(){
})