阿里面试题:瀑布流打造动态适配的视觉盛宴

325 阅读4分钟

什么是瀑布流布局:

在当今丰富多彩的网页设计领域,瀑布流布局因其独特的视觉效果和出色的自适应能力,成为了众多设计师和开发者的心头好。这种布局方式摒弃了传统的固定行列结构,转而采用按列排列、逐行填充的方式,为用户呈现了一种流动、错落有致的内容展示体验。比如:

微信图片_20240518171922.jpg微信图片_20240518171931.jpg 这两张图片就能看出来它们图片的排版是不对齐的那为什么要这样做呢

瀑布流布局的效果

瀑布流布局它能创造出一种多列、等宽但不等高的布局效果,特别适用于展示图像、画廊或者具有多种不同尺寸内容的列表。其核心特点和效果如下:

  1. 视觉错落美感:瀑布流布局通过将元素(通常是图片或者卡片)按列填充,使得每一列的高度不一致,形成一种自然的、流动的视觉效果。这种非统一的高度排列,给予页面一种动态且有机的外观,打破了传统网格布局的单调性。
  2. 自适应屏幕:布局能够很好地适应各种屏幕尺寸,特别是对于宽屏显示器,能够充分利用空间,使内容在不同设备上都能呈现出良好的视觉平衡。
  3. 动态加载:瀑布流布局常伴有无限滚动或点击加载更多功能,随着用户滚动页面,新的内容会不断加载并插入到当前列的末尾,保持浏览的连续性和探索感,提高了用户的参与度和停留时间。
  4. 内容优先:由于瀑布流布局能够灵活调整每列的高度,它能确保内容的完整性,尤其是对于图片而言,可以避免因固定高度而产生的裁剪或变形问题。
  5. 操作简便:用户在浏览时,只需滚动页面,无需水平拖动,就能轻松查看大量内容,提升了用户体验。

瀑布流布局是如何实现的呢

首先我们先放好二十张图片: image.png html和css代码为:

<!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/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>

  
</body>
</html>

想实现瀑布流核心是js代码的实现而要实现我们的目的我们先细分几点在慢慢实现:

  1. 确定每行图片数量:首先,通过获取屏幕宽度和单个图片的宽度,计算出一行内可以放置多少张图片。
  2. 动态摆放图片:从第二行开始,每次选择高度最小的那一列放置新的图片,同时更新该列的高度,确保图片始终填入最短的列中,营造出“瀑布”效果。
  3. 计算与调整:通过循环遍历所有图片,不断计算各列高度并进行比较,实时调整图片的位置,直至所有图片都被合理安置。

效果图为:

image.png

js代码实现:

window.onload=function(){  
    // 确定第一行能放 n 张图
      //1.获取屏幕宽度
      //2.读取图片的宽度
    //操作第 n+1 张摆放他的位置 放在高度最小的那一列
      //1.获取每一列的高度
      //2.更新这一列的高度
    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是因为上一段html代码引用js的代码写在了body上面所以window.onload的作用是让下面代码会在页面所有资源加载完成后执行。

以上内容,向我们展示了瀑布流布局不仅美化了网页的视觉表现,还提升了内容的展示效率和用户体验,尤其是在社交媒体、电商平台、博客和在线杂志等需要展示多样内容的网站中应用广泛。