瀑布流——艺术与技术的完美融合

863 阅读5分钟

引言:探索瀑布流的美学

当我们在网上冲浪时,不时会看到一系列不规则排列的内容,就好像瀑布一样自然地流淌,这种布局方式就被称为“瀑布流”(Waterfall Flow)。与传统的网页布局方式不同,瀑布流将内容分成多个列(类似于瀑布的水流),然后将内容按照顺序从上到下依次排列,当一列内容排满后,就自动流到下一列。

image.png

在当今数字时代,瀑布流的设计被广泛应用于网站和移动应用程序,为用户带来无与伦比的浏览体验。无论是社交媒体平台上展示的照片墙,还是电商网站上呈现的商品展示,瀑布流的布局都能够展现出其独特的视觉吸引力。

写代码前的准备

你也想实现这样美轮美奂的网页吗?那么你得注意以下几点:

1. 基本的前端技术知识

  • HTML/CSS: 瀑布流布局通常使用HTML和CSS进行结构和样式的定义。你需要了解HTML标签和CSS属性,特别是布局相关的属性。
  • JavaScript: 瀑布流的动态效果通常使用JavaScript实现,你需要掌握JavaScript的基本语法和DOM操作。

2. 开发环境

  • 你需要一个文本编辑器(比如Visual Studio Code、Sublime Text等)来编写代码。
  • 一个现代的Web浏览器,用于调试和测试你的瀑布流布局。 编写一个基本的瀑布流代码需要使用HTML、CSS和JavaScript。

3. 图片资源(或其他内容资源)

  • 如果你在瀑布流中展示的是图片,你需要有一组图片资源。这些资源可以是真实的图片文件,也可以是图片的URL地址。

代码的实现

准备HTML结构

首先,我们创建一个html文件并初始化,在body里面创建一个container的容器,在容器里面放若干个box,在box里面放自己想要展示的图片(注意:image文件夹的路径要与html文件同级;图片的地址可以是image文件夹内的,也可以是url地址)

<body>
  <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/10.jpg" alt="">
      </div>
    </div>
    ...
    ...//此处省略若干个box,共10张图,并将这10张图又copy了一份
  </div>
</body>
</html>

这样操作后我们运行html文件,看到的页面应该是这个样子的

image.png

然后,我们再到html文件的head里面编写CSS代码,由于CSS代码不长,所以直接在head里面写就OK,其主要目的是让图片浮动起来,并添加边框:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>瀑布流</title>
  <style>
    *{
      margin: 0;
      padding: 0;
    }
    #container{
      position: relative;
    }
    .box{
      float: left;
      padding: 5px;
    }
    .box-img{
      width: 150px;
      padding: 5px;
      border: 1px solid #ccc;
    }
    img{
      width: 100%;
    }
  </style>
</head>

在上面的代码中,我们创建了一个包含图片的容器container,在容器中存放了至少20张高度不一的图片(在上述代码中有所省略),并设置了基本的CSS样式来实现瀑布流布局。

此番操作后,页面显示如下(具体效果与页面大小有关): image.png

思考

我们要实现瀑布流的效果跟目前的差距在哪里?

我们按住ctrl+鼠标滚轮调节页面大小,发现图片始终是按行依次排满整个页面,后面的图片会另起一行继续排布。

于是我们发现,要实现瀑布流,那么图片应该见缝插针,说通俗一点就是下面一行的图片应该贴在上一行图片的下面,那么我们理解为,下一行的首个图片应该放置在上一行图片行高最小的图片下面,然后依次进行摆放。

image.png

思路已经有了,那么我们在js文件中来实现。

编写JavaScript代码

首先在html文件中引入js文件

<script src="waterfall.js"></script>

接下来,打开刚才创建的js文件,具体操作代码与注释如下:

// 读取用户屏幕第一行放了多少张图
// 操作下一张图,找到上一行最矮的高度,将图片排放到其下方
// 参数:parent - 包含图片的容器的ID,content - 图片元素的类名
function imgLocation(parent, content) { 
    // 获取父容器和所有图片元素
    var cparent = document.getElementById(parent);
    var ccontent = getChildElement(cparent, content);
    // 计算每张图片的宽度,以及每行可容纳的图片数量
    var imgWidth = ccontent[0].offsetWidth;
    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 { 
            // 需要操作的图片
            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(num);
}

// 获取指定父容器中指定类名的所有子元素
// 参数:parent - 父容器元素,content - 子元素的类名
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;
}

// 调用图片布局函数,传入父容器ID和图片元素类名,实现瀑布流布局
imgLocation('container', 'box');
console.log(imgLocation);
}

结语

以上就是一个简单的使用JavaScript创建瀑布流图片展示的实例。

感谢你选择阅读我的文章。希望你在学习中获得了乐趣,并且能够把所学应用到实际项目中。如果你有任何问题或者建议,可以评论区或私信联系我。

祝你编程愉快,前端之路越走越宽广!