瀑布流,又称瀑布流式布局。是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部。最早采用此布局的网站是Pinterest,逐渐在国内流行开来。国内大多数清新站基本为这类风格。
瀑布流布局效果
既多行等宽元素排列,等宽不等高,后面的元素依次排列在上一个元素后面
那么瀑布流的规则是什么哪?下面将用图解的方式分析一下瀑布流的算法
图解瀑布流
第一排图片的顶部会处于同一个高度,依次排列在顶端,哪第一排排满之后,后面的图片,也就是第6张图片应该怎样排列?
是这样吗?
可能有人认为会是这种方式进行排列,然而这样排列的方式是错误的,这样排列容易导致某一列可能会过长,而其他的列会过短,导致列之间高度相差过大的情况出现。那么怎样取解决这个问题那?答案就是利用定位在最短的一列下面进行排列,就像下图
看到这里,基本上已经理解了瀑布流的基本原理,接下来就是怎样去实现了!
瀑布流的实现
下面以Vue为例来展示怎样实现瀑布流效果
1.基本的布局
布局就比较简单的写一下哈~ 反正主要讲原理~
.v-waterfall-content{
width: 100%;
height: 100%;
position: relative;
}
.v-waterfall-item{
position: absolute;
}
.v-waterfall-item img{
width: 100%;
height: 100%;
}
2.瀑布流核心实现
首先在data
中定义一些基本的数据
waterfallList:[],//存放计算好的数据
waterfallImgWidth:200,//每一列的宽度
waterfallImgCol:5,//多少列
waterfallImgRight:10,//右边距
waterfallImgBottom:10,//下边距
waterfallDeviationHeight:[],//存放瀑布流各个列的高度
imgList:[]
然后给图片数组填充图片数据:
let imgArr = [
require('../assets/100x70.png'),
require('../assets/100x80.png'),
require('../assets/100x90.png'),
require('../assets/100x100.png'),
require('../assets/100x120.png'),
require('../assets/100x150.png'),
require('../assets/100x210.png'),
require('../assets/100x230.png'),
require('../assets/100x250.png')
];
for (let i = 0;i < 100;i++){
this.imgList.push(this.imgArr[Math.round(Math.random() * 8)]);
}
这里要注意,在js中存放静态文件链接的时候要用require
,不然不会显示:
可以看到,所有图片都挤到一起,根本没有流,下面谈一谈怎样让图片流起来
根据上面解释的瀑布流的基本原理,就是需要找到图片列里面高度最低的那一个,要找到最低的就需要记录没一列的高度,下面是记录列高度的实现:
//图片预加载,获取图片宽和高
imgPreloading(){
for (let i = 0;i < this.imgList.length;i++){
let aImg = new Image();
aImg.src = this.imgList[i];
aImg.onload = aImg.onerror = (e)=>{
let imgData = {};
//根据设定的列宽度求出图片的高度
imgData.height = this.waterfallImgWidth/aImg.width*aImg.height;
imgData.src = this.imgList[i];
this.waterfallList.push(imgData);
//调用图片位置计算方法
this.rankImg(imgData);
}
}
}
//计算图片偏移量
rankImg(imgData){
let {waterfallImgWidth,waterfallImgRight,waterfallImgBottom,waterfallDeviationHeight,waterfallImgCol} = this;
//找出当前最短列的索引
let minIndex = this.waterfallDeviationHeight.indexOf(Math.min.apply(null, this.waterfallDeviationHeight))
//获取最短列底部高度,既下一张图片的顶部高度
imgData.top = waterfallDeviationHeight[minIndex];
//计算左侧偏移,最短列索引*(右边距+列宽度)
imgData.left = minIndex*(waterfallImgRight+waterfallImgWidth);
//改变当前列高度
waterfallDeviationHeight[minIndex] += imgData.height + waterfallImgBottom;
}
这两个方法就是瀑布流的核心代码了,修改一下html代码,在刚才写的给图片数组填充完数据之后调用一下imgPreloading
方法,刷新浏览器就可以看到效果啦!
到这里基本上瀑布流的原理和核心思路大致明了了。瀑布流最重要的就是记录流的位置和计算图片的高度,
第一次写技术型博客,有写的不好的地方,还请多多指正,放上完整代码