实现瀑布流的几种方式(效果图)

一 . 使用css属性:column-count(不好)

column-count 是 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>
  </head>
  <style>
    .waterfall-container {
      column-count: 2; /* 根据需要调整列数 使用这个属性就能实现----------------------------*/
      column-gap: 20px; /* 列与列之间的间距 */
      width: 90%; /* 容器宽度 */
      margin: 20px auto; /* 外边距,使容器居中 */
    }
    .waterfall-item {
      /* 这里可以添加一些基本的样式,如背景色、边框等 */
      background-color: #f4f4f4;
      margin-bottom: 20px; /* 元素之间的间距 */
      break-inside: avoid; /* 防止内容跨列显示,但这不是所有浏览器都支持 */
      /* 为了让内容在容器内垂直居中,可以添加以下样式(可选) */
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      /* 设置一个固定的高度或最小高度来模拟不同高度的元素(可选) */
      /* height: 150px; 或 min-height: 100px; */
    }
    /* 为了更明显地看到效果,可以给每个元素添加一些随机高度 */
    /* 注意:实际项目中,你可能需要通过 JavaScript 来动态设置这些高度 */
    .waterfall-item:nth-child(odd) {
      height: 200px; /* 奇数项的高度 */
      background-color: red;
    }
    .waterfall-item:nth-child(even) {
      height: 150px; /* 偶数项的高度 */
      background-color: blue;
    }
  </style>
  <body>
    <div class="waterfall-container">
      <div class="waterfall-item">内容1</div>
      <div class="waterfall-item">内容2</div>
      <div class="waterfall-item">内容2</div>
      <div class="waterfall-item">内容1</div>
      <div class="waterfall-item">内容1</div>
      <div class="waterfall-item">内容2</div>
      <div class="waterfall-item">内容2</div>
    </div>
  </body>
</html>

是不是感觉瀑布流没那么难?一个样式就能实现我们要的效果,但是如果换成3列来看呢?

你就会发现他是垂直方向上的排列,只有第一列补充完后,第二列才开始补充,不是我们想要市面上所需要的横向排列瀑布流。

 .waterfall-container {
      column-count: 3; /* 根据需要调整列数 使用这个属性就能实现----------------------------*/
      column-gap: 20px; /* 列与列之间的间距 */
      width: 90%; /* 容器宽度 */
      margin: 20px auto; /* 外边距,使容器居中 */
    }

二 . 使用js定位实现(广泛使用)

先获取父盒子的宽度,试试能塞下多少个小图片,当第一行满了后,接下来就换行,就会获取第一行中最小图片的高度,后再获取它距离左边的宽度,然后才用定位属性,将第二行的图片添加到第一行最小图片高度的下面,具体不好讲,认真看代码就能理解了

<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    *{
      margin: 0;
      padding: 0;
    }
    #container{
      position: relative;
      /* overflow: hidden; */
      width: 1000px;

    }
    .box{
      float: left;
      padding: 5px;
      
    }
    .box-img{
      width: 250px;
      padding: 5px;
      /* border: 1px solid #aaa; */
    }
    img{
      width: 100%;
    }
  </style>
</head>
<body>
  <div id="container">
    <div class="box">
      <div class="box-img">
        <img src="https://gd-hbimg.huaban.com/ede93cf241ce93df1f824022ce1bc6dd042879819162e-fvCJH6" alt="">
      </div>
  </div>
    <div class="box">
      <div class="box-img">
        <img src="https://gd-hbimg.huaban.com/2d14622d76dbcd036cc47f240c80d5f1b9e6481da3430-r5cTIt" alt="">
      </div>
  </div>
    <div class="box">
      <div class="box-img">
        <img src="https://gd-hbimg.huaban.com/824306750839c34939b4345039e7425740598dd510a9c1-ewh29L" alt="">
      </div>
  </div>
    <div class="box">
      <div class="box-img">
        <img src="https://gd-hbimg.huaban.com/824306750839c34939b4345039e7425740598dd510a9c1-ewh29L" alt="">
      </div>
  </div>
    <div class="box">
      <div class="box-img">
        <img src="https://gd-hbimg.huaban.com/ce90e5b734b0c9933335d962a02ae6e8227965b6a984c-Gg1vRz" alt="">
      </div>
  </div>
    <div class="box">
      <div class="box-img">
        <img src="https://gd-hbimg.huaban.com/9fa5103953d1b3f2a70984f17395c1cf1eddc8db2af38-Q2fm1x" alt="">
      </div>
  </div>
    <div class="box">
      <div class="box-img">
        <img src="https://gd-hbimg.huaban.com/ce90e5b734b0c9933335d962a02ae6e8227965b6a984c-Gg1vRz" alt="">
      </div>
  </div>
</body>
<script>
  //网页完全加载后执行特定的代码或函数。这意呀着,当网页上的所有内容
  //(包括图片、样式表、脚本文件等)都加载完成后,window.onload 事件会被触发
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 = cParent.offsetWidth
      console.log(screenWidth,'父亲的宽度',cChild);
      var imgWidth = cChild[0].offsetWidth
      var num = Math.floor(screenWidth / imgWidth)
      console.log(num);
    //   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)
          console.log(boxHeightArr,minHeight);
          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
        }
      }
    }
  }
</script>
</html>

三 . 使用插件

npm瀑布流地址  https://www.npmjs.com/package/vue-waterfall-plugin

uniapp可以通过使用mescroll-uni插件来实现瀑布流效果。具体步骤如下: 1. 安装mescroll-uni插件 在uniapp项目的根目录下打开终端,输入以下命令安装mescroll-uni插件: ``` npm install mescroll-uni --save ``` 2. 引入mescroll-uni插件 在需要使用瀑布流效果的页面的vue文件中,引入mescroll-uni插件: ```javascript import MescrollUni from "@/components/mescroll-uni/mescroll-uni.vue"; ``` 3. 在template中使用mescroll-uni组件 在template中使用mescroll-uni组件,并设置相关属性: ```html <template> <view> <mescroll-uni :up="upOption"> <!-- 瀑布流内容区域 --> <view class="waterfall"> <view v-for="(item, index) in waterfallList" :key="index" class="waterfall-item"> <!-- 瀑布流内容 --> </view> </view> </mescroll-uni> </view> </template> ``` 其中,upOption是一个对象,用于配置上拉加载的相关参数,例如: ```javascript upOption: { auto: false, // 是否在初始化时自动触发上拉加载的回调函数 callback: this.loadMoreData, // 上拉加载的回调函数 noMoreSize: 5, // 当剩余数据小于等于noMoreSize时,触发noMore回调函数 noMore: true, // 是否显示无更多数据的提示 toTop: { // 回到顶部按钮的配置 src: "/static/images/top.png", offset: 1000, }, }, ``` 4. 在js中实现瀑布流效果 在vue文件的script标签中,实现瀑布流效果的相关逻辑,例如: ```javascript export default { data() { return { waterfallList: [], // 瀑布流数据列表 columnCount: 2, // 瀑布流列数 columnHeightList: [], // 瀑布流每列的高度列表 }; }, methods: { loadMoreData() { // 上拉加载更多数据的回调函数 // ... }, initColumnHeightList() { // 初始化瀑布流每列的高度列表 for (let i = 0; i < this.columnCount; i++) { this.columnHeightList.push(0); } }, getMinHeightColumnIndex() { // 获取当前高度最小的列的索引 let minHeight = this.columnHeightList[0]; let minHeightIndex = 0; for (let i = 1; i < this.columnCount; i++) { if (this.columnHeightList[i] < minHeight) { minHeight = this.columnHeightList[i]; minHeightIndex = i; } } return minHeightIndex; }, addWaterfallItem(item) { // 添加瀑布流内容项 const minHeightColumnIndex = this.getMinHeightColumnIndex(); this.waterfallList.push(item); this.columnHeightList[minHeightColumnIndex] += item.height; }, }, mounted() { this.initColumnHeightList(); // 加载初始数据 // ... }, }; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值