前言
今天我们来聊聊,阿里面试题:如何用JS实现瀑布流式页面布局。而瀑布流式页面布局在很多软件中都有使用,例如淘宝,小红书等。
如下:
那瀑布流是什么呢?
瀑布流(Waterfall Flow)是一种在网页设计和移动应用界面中常见的布局风格。瀑布流布局的主要特点是以多列的形式展示内容,其中每一列中的内容垂直排列,并且在不同列之间以不规则的方式进行排列,当一行图片排满之后,下一行图片将插入到上一行最矮的图片下面,以填充可用的空间。这种布局方式通常用于展示图片、新闻、社交媒体帖子、产品列表等多媒体和多项内容。
瀑布流的优点
- 吸引人眼:瀑布流式布局通常以不规则的方式展示内容,这可以吸引用户的注意力。由于内容以多个不同大小和形状的块呈现,用户更有可能浏览整个页面,以查看感兴趣的内容。
- 适应不同屏幕尺寸:瀑布流布局能够自适应不同屏幕尺寸,因为它会自动调整列数和块的大小以适应可用的空间。这使得网站在桌面、平板和移动设备上都能够提供良好的用户体验。
- 提高用户参与度:由于内容以紧凑的方式呈现,用户更有可能与页面上的多个元素互动,如点击链接、分享内容或留下评论。这可以提高用户的参与度和互动。
- 节省空间:瀑布流布局可以有效地利用页面空间,以容纳大量内容,而不会显得拥挤。这对于新闻、博客和社交媒体等内容丰富的网站非常有用。
效果实现
- 实现瀑布流式页面布局需要准备大量图片,我这里下载了40张图片,图片越多效果越好
- 编写HTML + CSS代码,给图片添加样式和布局
- 编写JS代码,根据自己的浏览器以及窗口大小,读取用户屏幕第一行放了多少张图 操作下一张图,找到上一行最矮的高度,将图片排放到其下方
HTMl + CSS
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>js瀑布流</title>
<style>
*{
margin: 0;
padding: 0;
}
#container{
position: relative;
}
.box{
float: left;
padding: 5px;
}
.box-img{
width: 150px; //给装图片的容器设置阴影,使图片更好看
padding: 5px;
border: 1px solid #ccc;
}
img{
width: 100%;
}
</style>
</head>
<body>
<div id="container">
<div class="box">
<div class="box-img">
<img src="./img/1.jpg" alt="">
</div>
<div> //此处省略剩下的39个box,代码一样
<div>
<body>
container容器来装所有图片,box放入每张图片* { margin: 0; padding: 0; }: 这是通用的CSS样式规则,它将所有HTML元素的默认外边距(margin)和内边距(padding)都设置为0。img设置了所有图片的宽度为100%,跟box-img高度一致.box{ float: left; padding: 5px; }让图片同行显示
JS
// 读取用户屏幕第一行放了多少张图
// 操作下一张图,找到上一行最矮的高度,将图片排放到其下方
imgLocation('container', 'box');
function imgLocation(parent, content) {
// 获取包含图片的容器元素
var cparent = document.getElementById(parent);
// 获取所有包含图片的子元素
var ccontent = getChildElement(cparent, content);
// 获取单张图片的宽度
var imgWidth = ccontent[0].offsetWidth;
// 计算一行可以容纳多少张图片
var num = Math.floor(document.documentElement.clientWidth / imgWidth);
// 设置容器的宽度,以容纳整数倍的图片宽度
cparent.style.cssText = `width: ${imgWidth * num}px`;
// 用数组存储每一列的高度
var BoxHeightArr = [];
// 遍历图片元素
for (var i = 0; i < ccontent.length; i++) {
if (i < num) {
// 如果是第一行的图片,直接记录它们的高度
BoxHeightArr[i] = ccontent[i].offsetHeight;
} else {
// 对于后续行的图片
// 找到最矮的列的高度
var minHeight = Math.min.apply(null, BoxHeightArr);
// 找到最矮的列的索引
var minIndex = BoxHeightArr.indexOf(minHeight);
// 设置当前图片的位置为绝对定位
ccontent[i].style.position = 'absolute';
// 设置当前图片的顶部位置为最矮列的高度
ccontent[i].style.top = minHeight + 'px';
// 设置当前图片的左侧位置为与最矮列对齐
ccontent[i].style.left = ccontent[minIndex].offsetLeft + 'px';
// 更新最矮列的高度,以包含当前图片的高度
BoxHeightArr[minIndex] = BoxHeightArr[minIndex] + ccontent[i].offsetHeight;
}
}
console.log(num);
}
function getChildElement(parent, content) {
// 获取指定类名的子元素
var contentArr = [];
var allContent = parent.getElementsByTagName('*');
for (var i = 0; i < allContent.length; i++) {
if (allContent[i].className == content) {
contentArr.push(allContent[i]);
}
}
return contentArr;
// 此行的代码不会执行,因为 return 之后的代码不会被执行
}
- 通过
imgLocation函数实现了瀑布流式的布局,首先计算一行可以容纳多少张图片,然后遍历图片,找到每张图片应该放置的位置。 getChildElement函数用于获取指定类名的子元素,用于从容器中提取包含图片的子元素。- 最终,页面中的图片会被动态排列,以适应用户屏幕的大小,从而创建瀑布流效果
最后的效果就是这样啦
今天的内容就到这啦,如果你觉得小编写的还不错的话,或者对你有所启发,请给小编一个辛苦的赞吧