前言
当面试官提出这样一个场景问题:在快手、小红书、淘宝...等大热的app中,有一种布局产品内容的方式,叫做瀑布流布局(它的主要特点是视觉上呈现出参差不齐的多栏布局,其中每个栏目宽度相等,但高度则根据内容(如图片、文章摘要等)自然调整,形成一种不规则而富有动态感的视觉效果),面试官给出的问题是如何具体实现瀑布流布局。。
接下来给出实例
实例是一个html页面,页面内放置有20张高度不一,宽度相同的图片,通过向左浮动的形式放置(float=left).(下图p1)理想的效果为:在第一行的图片摆放完后,下一张图片摆放在高度最小的一列下方,依此类推,摆放完所有的照片。(下图p2)
p1
p2
实现思路
先计算出你的屏幕一行能够放下多少张图片(screenWidth/imgWidth),假设为i张,将i张图片的高度记录在一个数组中,在放置第i+1张图片的时候,找到最短高度的一列,通过对父容器的相对位置定位到那一列的下方放置,放置完后更新最短列的高度设置为
boxHeightArr[i+1]=boxHeightArr[indexOfMin]+img.Height[i+1]
后面的图片也通过一样的思路通过for循环完成。
js核心代码:(有注释解题思路)
// --- 思路
//确定一行能放几张图片
//1、获取屏幕宽度
//2.获取图片的宽度
//操作第n+1张摆放它的位置 放在高度最小的那一列
//1.获取每一列的高度
//2.更新这一列的高度
function imgLocation(parent,child){
var cParent=document.getElementById(parent)
var cChild=cParent.getElementsByClassName(child)
var screenWidth=window.innerWidth //获取窗口宽度
var imgWidth=cChild[0].offsetWidth //获取图片的宽度
var num=Math.floor(screenWidth / imgWidth) //得到一行放多少张图片
cParent.style.width=`${imgWidth * num}px` //将容器大小设置为。。。
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]+=cChild[i].offsetHeight
}
}
console.log(boxHeightArr)
}
imgLocation('container','box')
}
html代码:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
#container{
position: relative;
}
.box{
float: left;
padding: 5px;
}
.box-img{
width: 150px;
padding: 5px;
border: 1px solid #eee;
}
img{
width: 100%;
}
</style>
</head>
<body>
<div id="container">
<div class="box">
<div class="box-img">
<img src="./img/1.webp" alt="">
</div>
</div>
<div class="box">
<div class="box-img">
<img src="./img/2.webp" alt="">
</div>
</div>
<div class="box">
<div class="box-img">
<img src="./img/3.webp" alt="">
</div>
</div>
<div class="box">
<div class="box-img">
<img src="./img/4.webp" alt="">
</div>
</div>
<div class="box">
<div class="box-img">
<img src="./img/5.webp" alt="">
</div>
</div>
<div class="box">
<div class="box-img">
<img src="./img/6.webp" alt="">
</div>
</div>
<div class="box">
<div class="box-img">
<img src="./img/7.webp" alt="">
</div>
</div>
<div class="box">
<div class="box-img">
<img src="./img/8.webp" alt="">
</div>
</div>
<div class="box">
<div class="box-img">
<img src="./img/9.webp" alt="">
</div>
</div>
<div class="box">
<div class="box-img">
<img src="./img/10.webp" alt="">
</div>
</div>
<div class="box">
<div class="box-img">
<img src="./img/1.webp" alt="">
</div>
</div>
<div class="box">
<div class="box-img">
<img src="./img/2.webp" alt="">
</div>
</div>
<div class="box">
<div class="box-img">
<img src="./img/3.webp" alt="">
</div>
</div>
<div class="box">
<div class="box-img">
<img src="./img/4.webp" alt="">
</div>
</div>
<div class="box">
<div class="box-img">
<img src="./img/5.webp" alt="">
</div>
</div>
<div class="box">
<div class="box-img">
<img src="./img/6.webp" alt="">
</div>
</div>
<div class="box">
<div class="box-img">
<img src="./img/7.webp" alt="">
</div>
</div>
<div class="box">
<div class="box-img">
<img src="./img/8.webp" alt="">
</div>
</div>
<div class="box">
<div class="box-img">
<img src="./img/9.webp" alt="">
</div>
</div>
<div class="box">
<div class="box-img">
<img src="./img/10.webp" alt="">
</div>
</div>
</div>
<script src="./base/index.js"></script>
</body>
</html>
最后我们就完成了面试官给出的需求,成功进入阿里....
总结
虽然这是阿里的一道面试题,但这其实并不那么困难。主要就是对算法思路的清晰,不要被那几张图片绕晕,思路主要就是对容器中元素的定位,以及对图片高度算法的处理..
如果小伙伴们能从中学到的话,是cc的荣幸~留个赞再走吧(共勉)