实现瀑布流式图片

352 阅读3分钟

打开小红书,我们可以看到图片是以一种看起来不规律的方式排列,如下:

image.png

这种排列方式就是瀑布流式,像瀑布流一样流下,我们看瀑布是不是会感觉很舒服,且视线会跟随水流而下,没错,这样设计的目的是为了使刷东西的人能够不停的往下翻,不停的想知道下面的图片和内容,令人上瘾。 好了,介绍完后,我们就来简单实现这种页面。

首先写html文件里的内容,设计好框架

<div id="container">
        <div class="box">
            <div class="box-img">
                <img src="./img/1.webp" alt="">
            </div>
        </div>

        ...20个box,放图片

    </div>

container里放20个box,每个box放图片。

其次写css样式:

<style>
        *{
            margin: 0;
            padding: 0;
            
        }
        #container{
            position: relative;

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

        }
        .box-img{
            width: 150px;
            padding: 5px;
            border: 1px solid #2eec48;
        }
        img{
            width: 100%;
        }
    </style>
  • *{}设计所有内边距外边距为0(因为初始都会有点内边距和外边距,需要消除)

  • #container{}定位position: relative;为box提供父类定位。

  • .box{}设置向左浮动,外边距5px。因为div是块级元素,会单独占用一行,要想图片挨个放一行,测需要float: left;要想图片之间要有间隙,显得更为美观而不那么拥挤,则设置盒子外边距padding: 5px;

  • .box-img{}设置盒子大小,外边距以及盒子的边。调整盒子大小,并设置外边距,将盒子的边设置成绿色,宽度为1px,实线。

  • img{}设置图片大小为盒子大小。

最后写js部分:

js是最关键的部分,这就要考验大家的思维和算法

第一行的图片很好排列,无非就是获取用户屏幕宽度,再获取每张图片大小,然后计算出每行可以放几张图片,再获取参考物的坐标放置放下一张的图片。

第n行图片怎么放呢?思路是这样的 获取每一列图片的高度,然后选取最小高度的图片的那一列,获取这列图片的最后一张图片的坐标位置,将图片放到这张图片的下面,最后更新这一列图片的高度,往复循环直到所有图片获取完。

代码:

// 获取到用户屏幕的宽度,决定了一行能放下几图
// 操作下一张图,放到上一行最矮的裂了下面

imgLocation('container', 'box')

function imgLocation(parent, content) {
    // 有多少张图
    var cparent = document.getElementById(parent)
    var ccontent = getChildElement(cparent, content)   // document.querySelectorAll('#container .box')
    // 每一个box的宽度
    var imgWidth = ccontent[0].offsetWidth
    var num = Math.floor(document.documentElement.clientWidth / imgWidth)
    cparent.style.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(BoxHeightArr);
    
  }

  function getChildElement(parent, child) {
    // 获取parent中所有的child
    var childArr = []
    var allChild = parent.getElementsByTagName('*')
    // 挑出来所有的box
    for (var i = 0; i < allChild.length; i++) {
      if (allChild[i].className == child) {
        childArr.push(allChild[i])
      }
    }
    return childArr
    
    
  }

瀑布流是大厂面试经常考的知识点,只要多加理解,多写代码,就可以很轻松回答类似问题,加油!