「高级干货」之经典阿里面试题:如何实现瀑布流布局?
前言
最近在学习前端布局时发现瀑布流布局挺好玩的,于是找到了一些例子发现,原来它一直在我们身边!!
瀑布流布局
瀑布流又称为瀑布流式布局。是当下比较流行的一种网页布局,以视觉表现为参差不齐的多栏布局为主,随着页面的滚动条不断向下滚动,这种布局会不断加载数据块并附加至当前尾部。
话不多说,直接看图:
瀑布流对于图片的展现,是高效而具有吸引力的,用户一眼扫过的快速阅读模式可以在短时间内获得更多的信息量,而瀑布流里懒加载模式又避免了用户鼠标点击的翻页操作,瀑布流的主要特性便是错落有致,定宽而不定高的设计让页面区别于传统的矩阵式图片布局模式,巧妙的利用视觉层级,视线的任意流动又缓解了视觉疲劳。
瀑布流布局优点很明显:
- 内容展示效果好,效率高
- 具有较强的吸引力
- 符合当下读者的阅读习惯
- 页面排版错落有致,有效的降低了界面复杂度,节省了空间
- 脱离传统布局模式,提高新颖度
缺点也不少:
- 图片加载速度慢:由于瀑布流布局的特性,需要加载大量的图片或内容块,可能导致页面加载速度变慢,特别是在网速较慢的环境下。
- 布局复杂:由于各个瀑布流块状元素大小不同,可能导致页面布局比较复杂,需要处理各个元素之间的间距排列。
- 信息呈现不规则:虽然瀑布流布局展示内容多样化了,但由于元素不规则排列,可能会导致一些内容被用户忽视或错过。
下面我们看如何实现此类瀑布流布局
请看html代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>实现瀑布流布局</title>
</head>
<body>
<div id="container">
<div class="box">
<div class="box-img">
<img src="../image/1.webp" alt="">
</div>
</div>
<!-- 此处省略了N 张图片 -->
</div>
</body>
</html>
因瀑布流css较少,可以添加style标签加入css样式
<style>
*{
margin: 0;
padding: 0;
}
#container{
position: relative;
}
.box{
padding: 5px;
}
.box-img{
width: 150px;
padding: 5px;
border: 1px solid #aaa;
}
img{
width: 100%;
}
</style>
由于全部都是div块级元素,当我们没做任何改变元素本身排列特性的操作时,其原本是如此图显示。
但我们要做的瀑布流式布局,我们使用float属性浮动来将图片放入同一行,修改css后如下图:
.box{
float: left;
padding: 5px;
}
当页面自适应宽度时又会出现如下所示:
为什么会这样呢?
其实这都是浮动属性float:left;在图片向左浮动时产生的问题
当我们的屏幕容不下那么多图片时,放不下的图片都会自动换行,往下一行靠左浮动,如图,第八张图片放不下,他会按照第七张图片的高度向左浮动,就像做滑滑梯一样,一直往左边靠,直到碰到比第七张图片更高的一列时,也就是碰到了第五张图停止浮动,后面图片也以此类推,就产生了这样的现象。
这个时候我们已经很接近瀑布流了,但只是这样的话我们会出现很多的空白区域浪费,所以我们用js来进一步改变图片的摆放位置,摆放规则是将放不下的图片放入高度最小的一列上。
完整的js和注解如下所示:
imgLocation('container','box')
function imgLocation(parent,child){
//确定第一行能放几张图片
var cParent = document.getElementById(parent) //获取容器container
var cChild = cParent.getElementsByClassName(child) //获取box且默认以数组返回
//1. 获取屏幕宽度
var screenWidth = window.innerWidth
//2. 读取图片宽度
var imgWidth = cChild[0].offsetWidth
var num = Math.floor(screenWidth / imgWidth) //向下取整函数 ,获取页面最多能容下多少张图片
cParent.style.width = `${imgWidth * num}px` //方便计算,直接将容器的宽度设为图片宽度 * 数量 的大小
//操作n+1张图片 摆放到第一行高度最小的那一列下面
var boxHeightArr = []
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 = cChild[minIndex].offsetLeft+'px'
//更新这一列的高度
boxHeightArr[minIndex] = boxHeightArr[minIndex] + cChild[i].offsetHeight
}
}
}
最终结果显示:
至此,一个自适应的瀑布流布局已完成。
总结
通过这个简单的瀑布流布局,我们能学到布局基本需要考虑到的一些因素,如图片的大小,信息块的大小,数组的基本使用方法,获取一些宽度、高度的方法等等。
本文介绍的是简单的瀑布流布局方法,其分为横向布瀑布流和竖向瀑布流,此处我们分析了一下竖向瀑布流,希望能够帮到你!
-
如果该篇文章对你有益,请不要吝啬你的赞哦,欢迎点赞和关注,也欢迎在评论区指正,谢谢。
转载自:https://juejin.cn/post/7369791641915817993