前言
今天我们来聊聊,阿里面试题:如何用JS实现瀑布流式页面布局。而瀑布流式页面布局在很多软件中都有使用,例如淘宝,小红书等。
如下:
那瀑布流是什么呢?
瀑布流(Waterfall Flow)是一种在网页设计和移动应用界面中常见的布局风格。瀑布流布局的主要特点是以多列的形式展示内容,其中每一列中的内容垂直排列,并且在不同列之间以不规则的方式进行排列,当一行图片排满之后,下一行图片将插入到上一行最矮的图片下面,以填充可用的空间。这种布局方式通常用于展示图片、新闻、社交媒体帖子、产品列表等多媒体和多项内容。
瀑布流的优点
- 吸引人眼:瀑布流式布局通常以不规则的方式展示内容,这可以吸引用户的注意力。由于内容以多个不同大小和形状的块呈现,用户更有可能浏览整个页面,以查看感兴趣的内容。
- 适应不同屏幕尺寸:瀑布流布局能够自适应不同屏幕尺寸,因为它会自动调整列数和块的大小以适应可用的空间。这使得网站在桌面、平板和移动设备上都能够提供良好的用户体验。
- 提高用户参与度:由于内容以紧凑的方式呈现,用户更有可能与页面上的多个元素互动,如点击链接、分享内容或留下评论。这可以提高用户的参与度和互动。
- 节省空间:瀑布流布局可以有效地利用页面空间,以容纳大量内容,而不会显得拥挤。这对于新闻、博客和社交媒体等内容丰富的网站非常有用。
效果实现
- 实现瀑布流式页面布局需要准备大量图片,我这里下载了40张图片,图片越多效果越好
- 编写HTML + CSS代码,给图片添加样式和布局
- 编写JS代码,根据自己的浏览器以及窗口大小,读取用户屏幕第一行放了多少张图 操作下一张图,找到上一行最矮的高度,将图片排放到其下方
HTMl + CSS
<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
函数用于获取指定类名的子元素,用于从容器中提取包含图片的子元素。- 最终,页面中的图片会被动态排列,以适应用户屏幕的大小,从而创建瀑布流效果
最后的效果就是这样啦
今天的内容就到这啦,如果你觉得���编写的还不错的话,或者对你有所启发,请给小编一个辛苦的赞吧