阿里经典面试题:瀑布流布局

什么是瀑布流

瀑布流布局,作为一种现代网页设计中的创新布局方式,以其独特的视觉风格和流畅的用户体验在众多网站设计中脱颖而出。这种布局模式被形象地称为"瀑布流",因其形态酷似自然界的瀑布,内容模块按照不规则的垂直顺序排列,每一列高度各异,如同水流般自由流淌。

就好像以下页面一样:

瀑布流布局的核心特征

  1. 多列等宽不等高:瀑布流布局以多列的形式展现内容,每列宽度保持一致,而高度则根据所容纳内容的大小动态调整,形成错落有致的视觉效果。
  2. 动态加载与无限滚动:用户在浏览过程中,随着滚动页面,新的内容块会自动加载,实现了"无尽"的内容流,减少了分页操作,提升了浏览连贯性。
  3. 视觉吸引力:尤其擅长展示图片或视觉元素丰富的媒体内容,为用户提供了沉浸式的浏览体验,增加了页面的观赏性和互动性。

瀑布流布局的优点

  1. 提升用户体验:通过无限滚动的方式,用户无需频繁点击翻页,即可轻松浏览更多内容,增强了浏览的连续性和便捷性。
  2. 简化导航:将大量内容整合在单个页面上,减少了传统导航的复杂性,让用户能更直接地接触到信息。
  3. 增强参与度:鼓励用户通过持续滚动来探索更多内容,延长了用户在网站上的停留时间,增加了互动可能性。
  4. 视觉冲击力:尤其适合视觉驱动型网站,如图片分享平台,能够有效展示大量精美图片,提升页面整体吸引力。

设计瀑布流布局

  1. 先获取屏幕的大小
  2. 获取图片的宽度
  3. 确定第一行能放几张图(n张)
  4. 操作第 n+1 张 摆放它的位置,将其放在高度最小的那一列
  5. 获取每一列的高度
  6. 放入图片后,更新这一列的高度

实操

HTML

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="./index.js"></script> 
  <style>
    *{
      margin: 0;
      padding: 0;
    }
    #container{
      position: relative;
    }
    .box{
      float: left;
      padding: 5px;
    }
    .box-img{
      width: 150px;
      padding: 5px;
      border: 1px solid #aaa;
    }
    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/9.webp" alt="">
      </div>
    </div>
    <div class="box">
      <div class="box-img">
        <img src="./img/10.webp" alt="">
      </div>
    </div>
  </div>
</body>
</html>

假设body里面放了好多张,这里未完全显示,不过格式基本都是一样的。别忘了这么多相同的东西不用一个个敲哦,有方便的方法( Emmet

因为css样式比较少我就放在html里面了,要注意这里我将JS的引用放在里html的头部,一般都是在body标签的末尾,所以待会在写JS的时候会添加一些东西,这样就不会影响了。

还要注意,图片的路径别出错了<img src="./img/1.webp" alt="">,下面是没有调整的样子

js

接下来来看看js的代码吧,这才是重中之重!!!

js 复制代码
window.onload = function() {
    imgLocation('container', 'box')  
  
    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`
  
      // 操作第 num+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
        }
      }
    }  
  }
  • window.onload = function() {}js 写在头部,加上这个就不影响了,之后的代码写在里面就可以了;
  • imgLocation('container', 'box') 运用封装的思维
  • .offsetWidth 获取宽度
  • .offsetHeight 获取高度
  • .offsetLeft 获取距离父元素的左侧距离
  • .offsetTop 获取距离父元素的顶部距离
  • ...boxHeightArr ...是解构数组的操作
  • indexof(arr) 会返回数组的下标

OK了,来看看我们的简易版瀑布流

相信你也可以做出来,或许我们可以利用这个来存放照片,也还不错🥰

相关推荐
猫猫不是喵喵.3 小时前
Vue3 Props 属性
前端·javascript·vue.js
HeiSenBerg7 小时前
Android 网络协议全解析:从 TCP 三次握手到 HTTPS 加密,一篇就够了
面试
jarvisuni7 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·javascript·算法
破z晓9 小时前
javascript 导出excel表
开发语言·javascript·excel
小罗水10 小时前
第17章 后台管理端与演示支持
javascript·vue.js·ecmascript
乐思智能科技有限公司10 小时前
PLECS软件学习使用(二)直流电机基本系统模型
人工智能·算法·机器学习·面试·职场和发展
GitLqr11 小时前
深度拆解 Dart 事件循环:从面试题看清 Microtask 与 Event Queue 的执行顺序
flutter·面试·dart
haerapi11 小时前
用 System V 共享内存实现本机高速 IPC:从原理到可运行环形队列
面试
万少12 小时前
DeepSeek-V4-Flash 正式版上线了,但这 3 个坑我帮你提前踩了
前端·javascript·后端
宁风NF12 小时前
JavaScript:网络请求与前端通信
开发语言·前端·javascript·网络·学习·ecmascript