开篇
瀑布流式布局(WaterFallLayouts)
瀑布流式布局是一种流行的网页设计布局方式,适用于展示宽度一致但高度不一致的图片等内容。以图片展示为例,简单来说:若干张图片先排满第一行,当一行排满后,新的图片会紧接着上一行高度最小的那一列开始在下一行显示,从而形成了参差不齐、视觉上类似瀑布流水效果的布局。
如图:
实质上,瀑布流式布局方式有以下特点:
多列布局:页面被划分为多个等宽的列,每列独立填充内容。
动态高度:各列中的内容块(如图片、文章摘要等)高度不固定,依据内容自适应,使得列的高度各不相同。
逐行填充:内容逐个添加到当前最短的列中,以保持页面整体的平衡感和视觉流畅性。
无限滚动或分页加载:随着用户滚动页面,更多的内容会动态加载并添加到布局的尾部,提供了良好的用户体验和持续的浏览体验。
实际运用场景
瀑布流布局最早因图片分享网站Pinterest的使用而广为人知,之后被广泛应用于各类网站和应用中。我们来看看生活中的例子:
许多社交APP中都如此推崇这一布局方式,自然是因为这种布局方式好处多多,不过这里不加赘述。我们直接进入到思路分析,开始手搓。
此处是需要用到的html css代码:
<style>
* {
margin: 0;
padding: 0;
}
#container {
position: relative;
width: auto;
}
.box {
/*块级*/
float: left; /*从左往右排列*/
padding: 5px;
}
.box-img {
width: 150px;
padding: 5px;
}
img {
width: 100%;
/*高不需要设,会自动按比例缩放*/
}
</style>
<body>
<div id="container">
<div class="box">
<div class="box-img">
<img src="./img/1.jpg" alt="转存失败,建议直接上传图片文件">
</div>
</div>
</body>
JS部分实现思路
- 获取浏览器窗口的宽度screenWidth
var screenWidth = window.innerWidth;
2.获取图片宽度Width(固定),计算一行能放下几张图片
var imgWidth = cChild[0].offsetWidth;
var num = Math.floor(screenWidth / imgWidth);
//设置当前photos的父容器宽度
cParent.style.width = `${imgWidth * num}px`;
3.将第一行每一列图片的高度Height放入数组
for (var i = 0; i < cChild.length; i++) {
if (i < num) {
boxHeightArr.push(cChild[i].offsetHeight); //第一行每一列图片所在box的高度
}
}
4.根据每一列的高度,按从小到大的顺序摆放后面几行的图片
for (var i = 0; i < cChild.length; i++) {
if (i < num) {
boxHeightArr.push(cChild[i].offsetHeight);
}else{
//找出最矮列的高度
var minHeight = Math.min(...boxHeightArr) //...解构
//找出高度最小列的下标
var minIndex = boxHeightArr.indexOf(minHeight)
//设置图片的摆放位置
cChild[i].style.position = 'absolute'
cChild[i].style.top = minHeight + 'px'
cChild[i].style.left = imgWidth*minIndex + 'px'
//更新这一列的高度
boxHeightArr[minIndex] = boxHeightArr[minIndex] + cChild[i].offsetHeight
}
}
5.将上述代码放入函数体,查看效果
//此处传入的分别是id名和类名
imgLocation("container", "box");
短短几步,大体上就实现了预期的排列效果**,快动手试试吧!
优化部分
光看效果确实不错,不过在实际体验后,不难发现,只是前面的部分代码还不足以满足用户的动态操作,主要体现在以下方面:
一、当往左减小浏览器窗口宽度时,右边的图片会被隐藏?
这个问题,观察代码分析不难知道,js的代码并未监控浏览器页面的一个缩放行为,自然不能够动态变化图片排列,我们只需要加上部分代码即可。
function resize(){
imgLocation("container", "box");
}
window.addEventListener('resize',resize)
二、当往左减小浏览器窗口宽度后,继续向右还原其宽度,部分图片练成了“隐身术”?
而这个这个bug的原因在于:当浏览器窗口变宽时,已经移出可视区域的图片应当重新回到流中合适的位置。为了解决这个问题,我们需要相应地调整所有图片的位置。
//排列前确保图片定位的参数为空
for(var i = 0; i < cChild.length;i++){
cChild[i].style.position = ''
cChild[i].style.top = ''
cChild[i].style.left = ''
}
解决了这些问题,至此,就是这个瀑布流布局方式的简单示例。
总结
瀑布流布局方式的实现其实不难,但是细节也需要注意,实际开发的情况更加复杂,我们可能需要注意以下方面:
1. 优化图片加载与布局
- 懒加载:对于瀑布流布局,图片较多时可以采用懒加载技术,即滚动到可视区域时才加载图片,这有助于提高页面首次加载速度。
- 图片尺寸预加载:在自己的项目中,可以通过JavaScript预加载图片尺寸,以便更快地计算布局,减少页面重排重绘。
2. 优化布局算法
- 考虑图片的实际尺寸:在计算布局时,除了基于屏幕宽度和图片宽度计算列数,还应该考虑图片的实际尺寸(尤其是高度),以避免在窗口缩放时产生过多的空白或重叠。
3. 测试与兼容性
- 跨浏览器测试:确保在不同浏览器和设备上都能正常工作,特别注意一些老版本浏览器可能对CSS3特性支持不足。
- 触摸设备友好:考虑到移动设备用户,确保触控操作流畅,布局在各种屏幕尺寸和方向上都能良好展示。