如何用JavaScript实现一个瀑布流?

1,477 阅读3分钟

前言

首先,何为瀑布流? 其实很简单,像我们现在日常使用手机软件例如淘宝、抖音等时,经常会发现软件的页面布局如下图所示:

微信图片_20241031115759.png

当我们在电脑上打开百度图片任意搜索后也会看到:

image.png

像这种哪怕图片高度不同,但是我能让他宽度一致,并且要让页面的图片像瀑布一样参差不齐却又错落有致的向下走的页面就被叫做瀑布流。

那么,瀑布流为什么在日常生活中如此常见,能受到广大软件页面的喜欢呢? 打个比方,当你打开淘宝搜索你想要的商品时,你可能随便滑滑就看见让你心仪的产品,可是你稍稍一瞥,发现页面底部另外一张露出一小半的图片同样让你觉得不错,所以你会一直向下翻动,可能过一会儿在你敲定了要买的商品时,另外一个商品引起你的注意,时间就在指尖悄然流逝,于是作为用户的你会在淘宝这个购物软件上花上大把时间。至于为什么要让你多花时间在这上面,你问我,诶嘿,我也不知道。

代码思路及实现

我们该如何实现它呢? 首先敲定好代码的框架,对于用户所使用的设备不同,那么图片在一行中显示的数量也就不同,所以我们应该先确定一行能放入几张图片,要怎么确定呢?于是就细分成两步,第一步:获取用户屏幕的宽度 第二步:获取图片的宽度 到这里为止框架已经搭建好一半了 在第一行放满图片之后 我们应该思考的是如何将接下来的每一张图片置于上一行最短高度图片的下面 在这里也分成两步 第一步:获取第一行中每一张图片的高度 第二步:更新这一列的高度

至此,代码框架构架完成。接下来我们来实现它。

首先创建一个html文件,创建一个id为container的类,然后将我们想要插入的每一张图片都放进一个名为box的类中,再嵌套进container中。

接下来进入JS部分, 我们定义一个函数让它完成整个瀑布流,定义两个变量来获取container和box后进行我们的第一部分,获取用户屏幕宽度和图片宽度。

imgLocation('container','box')

function imgLocation(parent,child){
  var cParent = document.getElementById(parent)
  var cChild = document.getElementsByClassName(child)

  var scrennWidth = window.innerWidth  //获取用户屏幕宽度
  var imgWidth = cChild[0].offsetWidth  //获取图片宽度
  var num = Math.floor(scrennWidth / imgWidth)  //一行能放进的图片数量
  cParent.style.Width = `${imgWidth * num}px`

然后再处理第二行及后面的所有图片

var boxHeightArr = []
  for(var i = 0 ; i < cChild.length ; i++){
    if(i < num){ //只能存入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
    }
  }
}

到这里代码就全部完成了,代码效果图如下:

image.png

小结

瀑布流被广泛应用于各大软件及页面上,并且实现也较为简单,希望能对大家有所帮助。