大厂也在用的:HTMl+CSS+JS实现瀑布流式页面布局

什么是瀑布流式页面布局

下面看几个现实的案例:

小红书中的瀑布流式页面布局

手机淘宝中的瀑布流式页面布局:

介绍

瀑布流式布局页面是什么?

页面上给人一种参差不齐的多栏布局,其中元素大部分为图片,图片的宽度是统一固定的,但是由于高度不一样,第一行图片排满之后,新的图片会插入到第一排中高度最低的图片下面,并更新高度,如此循环,最终达到瀑布流式的效果。

优点:

  1. 吸引眼球: 瀑布流布局的不规则排列方式能够引起用户的兴趣,使界面更吸引人。用户会感到好奇,想要浏览所有的项目,因为每个项目都以不同的方式呈现。
  2. 有效利用空间: 瀑布流布局可以充分利用页面空间,无论是横向还是纵向滚动,都可以容纳很多项目。这对于展示大量内容或产品非常有用。
  3. 适应性: 瀑布流布局可以适应不同屏幕大小和设备类型,因为它是响应式设计的一部分。这意味着它可以在桌面电脑、平板电脑和移动设备上都有良好的表现。
  4. 提高用户参与度: 用户通常更愿意探索页面上的不同项目,因为每次滚动都可能带来新的发现,从而增加了用户的参与度和浏览时间。

缺点:

  1. 信息层次不明确: 由于项目的不规则排列,瀑布流布局可能会使用户难以识别内容的层次和重要性。重要内容可能会被埋没在次要内容中。
  2. 不适用于所有类型的内容: 瀑布流布局更适合视觉导向的内容,如图片、照片、商品展示等。对于需要详细信息或结构化内容的页面,这种布局可能不够合适。
  3. 加载时间问题: 当页面包含大量项目时,瀑布流布局可能导致页面加载时间变长,特别是在网络连接较慢的情况下。这可能会影响用户体验。
  4. 有限的导航性: 用户可能会发现导航和查找特定项目变得更加困难,因为项目的位置是不固定的。这可能会使用户在页面上迷失方向。

代码实现

HTML:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>js瀑布流</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <!-- container容器用来存放box容器,一个box放一张图片 -->
  <div id="container">
      <!-- 根据自己的需求添加图片的数量 -->
    <div class="box">
      <div class="box-img"><img src="./img/1.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="box-img"><img src="./img/2.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="box-img"><img src="./img/3.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="box-img"><img src="./img/4.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="box-img"><img src="./img/5.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="box-img"><img src="./img/6.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="box-img"><img src="./img/7.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="box-img"><img src="./img/8.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="box-img"><img src="./img/9.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="box-img"><img src="./img/10.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="box-img"><img src="./img/1.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="box-img"><img src="./img/2.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="box-img"><img src="./img/3.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="box-img"><img src="./img/4.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="box-img"><img src="./img/5.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="box-img"><img src="./img/6.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="box-img"><img src="./img/7.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="box-img"><img src="./img/8.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="box-img"><img src="./img/9.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="box-img"><img src="./img/10.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="box-img"><img src="./img/1.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="box-img"><img src="./img/2.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="box-img"><img src="./img/3.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="box-img"><img src="./img/4.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="box-img"><img src="./img/5.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="box-img"><img src="./img/6.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="box-img"><img src="./img/7.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="box-img"><img src="./img/8.jpg" alt=""></div>
    </div>
    <div class="box">
      <div class="box-img"><img src="./img/9.jpg" alt=""></div>
    </div>
  </div>

  <script type="text/javascript" src="waterfall.js">
    
  </script>
</body>
</html>

`

CSS:

CSS 复制代码
*{
  margin: 0;
  padding: 0;
}

.box{
  float: left;
  padding: 5px;
}

.box-img{
  width: 165px;  // 图片的宽度,他会决定一行能放多少张图片
  padding: 5px;
  border: 1px solid #ccc;
}

img{
  width: 100%;
}

JS:

js 复制代码
// 读取用户屏幕第一行放了多少张图
// 操作下一张图,找到上一行最矮的高度,将图片排放到其下方

function imgLocation(parent,content){  // 当前有多少图片要摆放

  // 获取到大盒子cparent(大盒子内存放了很多个box,其中每一个box盒子存放着一张图片)
  var cparent = document.getElementById(parent)
  // 将大盒子cparent中所有的box盒子存放在一个数组ccontent中
  var ccontent = getChildElement(cparent,content) 
  // 获取到第一张图片的宽度(已知每一张图片的宽度都相同)
  var imgWidth = ccontent[0].offsetWidth
  // 其中num计算后为页面一行能存放图片的张数,也就是一行能放多少个box盒子
  // document.documentElement.clientWidth 获取整个屏幕的宽度
  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{   // 要操作的图
       
      /* 找到高度最小值图片对应的下标 */
      // 获取到第一行中的高度最小值
      // apply为借用前面的Math.min方法给数组,不能直接使用Math.min找到数组中的最小值
      var minHeight = Math.min.apply(null,BoxHeightArr) 
      // 找到高度最小值对应在数组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'
      /* 新插入的图片进行定位 */

      // 更新这一列的高度(这里很关键,因为数组中只会存放num(一行放图片的数目)个元素,
      // 所以插入新图片后原来高度最小值就未必是最小了)
      BoxHeightArr[minIndex] = BoxHeightArr[minIndex] + ccontent[i].offsetHeight
    }
  }
}


// 定义一个函数获取一个容器内中某个容器的数目(此处为获取所有container容器内的box容器)
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
}


imgLocation('container','box')

最终代码实现效果

图片只有8张时(正好放在一行)

多放几张图片

图片多到排满整个页面

留言

如果以上内容对你有些许帮助,还请劳烦给博主送一个小心心♥(ˆ◡ˆԅ)

本人Gitee仓库链接(也要♥(ˆ◡ˆԅ)):codeSpace: 记录coding中的点点滴滴 (gitee.com)

相关推荐
腾讯TNTWeb前端团队5 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰8 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪9 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪9 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy9 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom10 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom10 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom10 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom10 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom10 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试