小程序瀑布流实现

news2025/4/27 8:06:00

什么是瀑布流布局

瀑布流布局,一般等宽,不等高的列表排列

原理是找出高度之和最小的那一列,在高度最小列继续添加元素

可以通过 absolute 定位实现,动态计算每一项的 topleft

在这里插入图片描述

封装瀑布流方法

function getAllRect(context, selector) {
  return new Promise(function (resolve) {
    wx.createSelectorQuery()
      .in(context)
      .selectAll(selector)
      .boundingClientRect()
      .exec(function (rect) {
        if (rect === void 0) {
          rect = []
        }
        return resolve(rect[0])
      })
  })
}

/**
 * 瀑布流
 * @param {*} context 页面或组件this对象
 * @param {string} selector 选择器
 * @param {Object} options
 * @param {number=375} options.width 屏幕宽度
 * @param {number=2} options.column 列数
 * @param {number|string} options.gap 每列直接的间隙
 * @param {number=0} options.padding 整个列表左右的padding
 * @param {number=0}
 * @returns {Array} 计算每项的top、left、height的数组
 */
async function waterFall(context, selector, options = {}) {
  let items = await getAllRect(context, selector)
  if (items.length <= 0) return []
  let { gap = 15, column = 2, padding = 0, width = 375, firstColumnToTop = 0 } = options
  // 1- 确定列数  = 页面的宽度 / 图片的宽度,单例的宽度
  let itemWidth = items[0].width
  // 定义每一列之间的间隙 px
  if (gap === 'auto') {
    gap = (width - itemWidth * column) / (column - 1)
  }
  let _columnHeightArr = [] // 保存每列高度
  let result = []

  for (let i = 0, len = items.length; i < len; i++) {
    if (i < column) {
      // 2- 确定第一行
      let top = firstColumnToTop
      let left = (itemWidth + gap) * i + padding
      // 瀑布流列表左右padding
      if (i === 0 || i === len - 1) {
        left = padding
      }
      _columnHeightArr.push(items[i].height - top)
      result.push({
        top,
        left,
        height: items[i].height,
      })
    } else {
      // 其他行
      // 3- 找到数组中最小高度  和 它的索引
      let minHeight = Math.min(..._columnHeightArr)
      let minIndex = _columnHeightArr.findIndex((item) => item === minHeight)
      // 4- 设置下一行的第一个盒子位置
      // top值就是最小列的高度 + gap
      result.push({
        top: _columnHeightArr[minIndex] + gap,
        left: result[minIndex].left,
        height: items[i].height,
      })

      // 5- 修改最小列的高度
      // 最小列的高度 = 当前自己的高度 + 拼接过来的高度 + 间隙的高度
      _columnHeightArr[minIndex] = _columnHeightArr[minIndex] + items[i].height
    }
  }

  return result
}

使用

vim demo.wxml

    <!--需要子元素撑大父元素高度的情况,才需要设置height-->
    <view class="goods_list flex flex-wrap relative" style="width:100%;height:{{height}}">
        <block wx:for="{{list}}" wx:key="index">
          <view class="goods_item" style="position:absolute;top:{{ item.top }}px;left:{{ item.left }}px"
                bindtap="handleItem" data-item="{{item}}">
            <view class="goods_img">
              <goodsImage detail="{{ {imgUrl:item.goodsIcon} }}" isAllowCash="{{true}}">
              </goodsImage>
            </view>
            <view class="goods_mes">
              <view class="goods_name g-t-over2">{{item.goodsName}}</view>
              <view class="goods_price">{{item.price}}</view>
            </view>
          </view>
        </block>
    </view>

vim demo.js

// 需要在节点加载到页面后调用
onReady() {
  const { screenWidth, list } = this.data
  waterFall(this, '.goods_item', { width: screenWidth, gap: 'auto' }).then((arr) => {
    if (!arr.length) return
    let lastNode = arr[arr.length - 1]
    let height = lastNode.top + lastNode.height + 'px'
    this.setData({
      list: list.map((item, index) => ({ ...item, ...arr[index] })),
      height,
    })
  })
}

效果

在这里插入图片描述

小结

既然都封装成函数了,为什么不封装成组件调用呢?

组件调用可以参考这个小程序的瀑布流组件me-waterfall

我看了这个组件的源码,用到组件间关系来实现瀑布流结构,整个瀑布流组件内部也需要父子组件关系,父组件监听子组件插入元素,获取元素的动态高度,往高度最小列添加新元素。

但是我引入使用,在组件内使用me-waterfall 组件,组件间关系方法 linked 不生效,官方论坛也找不到原因,便弃用。
类似这样的结构:

<!--page.wxml-->
<view>
	<goodsList />
</view

<!--goodsList.wxml-->
<view>
	<me-waterfall>
	  <me-waterfall-item wx:for="{{list}}" wx:key="index">
	    <image src="{{item.imgUrl}}" style="width:100%;height:{{item.height}}px" />
	  </me-waterfall-item>
	</me-waterfall>
</view

于是,自己封装一个方法使用。便有了此文。

封装成方法也有优点,不需要引入组件,简单引入一下方法调用即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/48558.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTML期末作业课程设计期末大作业--小米网站开发者平台首页 1页

⛵ 源码获取 文末联系 ✈ Web前端开发技术 描述 网页设计题材&#xff0c;DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业 | 公司官网网站 | 企业官网 | 酒店官网 | 等网站的设计与制| HTML期末大学生网页设计作业&#xff0c;Web大学生网页 HTML&#xff1a;结构 CSS&#x…

MyBatis学习笔记(2022-11-30)

熬过无人问津的日子才会有诗和远方。 文章目录一、MyBatis简述二、快速入门三、MyBatis配置文件详解1. MyBatis核心配置文件1.1 configuration&#xff08;配置&#xff09;1.2 properties&#xff08;属性&#xff09;1.3 environments&#xff08;环境配置&#xff09;1.4 ty…

vue项目 element UI input框扫码枪扫描过快 出现数据丢失问题(已解决二)

项目需求: 输入框要掉两个接口&#xff0c;根据第一个验证接口返回的code&#xff0c;弹不同的框&#xff0c;点击弹框确认再掉第二个接口 根据客户现场反应&#xff0c;扫描枪快速扫描会出现 料号前几位字符丢失 不完整的问题。于是开始了测试之路。 解决方案探索 1.首先考…

数据可视化,销量第一的新能源汽车是什么?比亚迪新能源汽车销量接近60万辆

去年以来&#xff0c;新能源汽车火热度席卷全球&#xff0c;中国的新能源汽车无论制造或者销售&#xff0c;数量增长迅猛。下面小编用一款数据可视化软件&#xff0c;带你用可视化数据解读高端制造背后&#xff0c;中国新能源汽车的具体销售情况。同样如果你工作上有数据报表需…

[附源码]计算机毕业设计springboot酒店物联网平台系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

全国省市县 经纬度的 json数据(提供原文件),写Java代码,入库(提供代码)

目录 1 需求2 分析1 需求 有一个全国省市县 经纬度的 json数据,我想要使用代码入库 如何操作,代码咋写 2 分析 首先分析json结构, 一般拿到一个json数据,如果最外层不是 { } 包裹的,那么自己手动加一个 以上这个是自己加的,这个就是key 值就是list 集合 分析完json数…

【并发】深入理解Java线程的底层原理

线程基础知识 线程与进程 进程 操作系统会以进程为单位&#xff0c;分配系统资源&#xff08;CPU时间片、内存等资源&#xff09;&#xff0c;进程是资源分配的最小单位。 当一个程序被运行&#xff0c;从磁盘加载这个程序的代码至内存&#xff0c;这时就开启了一个进程。 线…

LDcad零件新增与导入

LDcad大颗粒小颗粒套装导入方法&#xff0c;以后LDcad也可以用套装搭建模型了。 LDcad大颗粒小颗粒套装导入方法&#xff0c; 以后LDcad也可以用套装搭建模型了。 有个遗憾&#xff0c;就是零件不全。 具体导入方法看下文。 我们可以看到。这些套装都有对应的图标。方便…

环境温湿度在线监测如何实现?有何应用场景?

温度、湿度等环境数据与人们生活生产息息相关。温湿度传感器作为能将温度量和湿度量转换成容易被测量处理的电信号的设备或装置&#xff0c;广泛应用于工农业生产、气象、环保、国防、科研等经常需要对环境或设备的温度与湿度进行测量的领域&#xff0c;因此也产生了对温湿度远…

ASP.NET Core 3.1系列(15)——Entity Framework Core之DB First

1、前言 本文开始介绍一些关于Entity Framework Core的内容。在EFCore中&#xff0c;常用的为DB First模式和Code First模式&#xff0c;下面就来介绍一下如何在EFCore中使用DB First模式生成实体类和数据库上下文。 2、创建测试数据库 在SQL Server中新建一个数据库Dao&…

2016-04《信息资源管理 02378》真卷解析,逐题解析+背诵技巧

本系列博客合计 21 篇&#xff0c;每篇都将解析一张《信息资源管理》真卷&#xff0c;并附带答案解析与背诵技巧。 全国 2016 年 4 月自学考试信息资源管理试题&#xff08;02378&#xff09; 单选题 1、按信息表现形式划分&#xff0c;信息可分为&#xff08;C&#xff09; …

JavaScript的Web api接口

JavaScript的Web api 文章目录JavaScript的Web api选中元素事件操作元素获取/元素内容获取/修改元素属性获取/修改表单元素属性实现一个显示/隐藏 密码的功能实现一个加减计算器复选框全选/全不选获取/修改样式属性点击文字放大字体实现白天模式与夜间模式的切换操作节点新增节…

【附源码】计算机毕业设计JAVA住房公积金筹集子系统的网站系统

【附源码】计算机毕业设计JAVA住房公积金筹集子系统的网站系统 目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xf…

3D漫游:所见即所得的形式,构建线上数字展厅

企业在数字化转型的大环境下&#xff0c;较为常用的当属数字展厅了&#xff0c;数字展厅能够为企业、行业协会、展销基地以及体验中心助力&#xff0c;以所见即所得的形式构建线上数字空间&#xff0c;满足企业的数字化展示和数字化营销。3D漫游&#xff0c;更加沉浸式的三维空…

使用 Hibernate Envers 进行实体审计

业务应用程序中的常见要求是在特定数据更改时存储版本控制信息;当某事发生变化时&#xff0c;谁改变了它&#xff0c;改变了什么。在这篇博文中&#xff0c;我们将介绍Hibernate Envers&#xff0c;它是Hibernate JPA库的一个组件&#xff0c;它为实体类提供了一个简单的审计/版…

【Linux网络配置实战】服务器Network静态路由配置

【Linux网络配置实战】服务器Network静态路由配置一、环境介绍1.环境规划2.实验目的二、检查各节点IP地址1.检查server01服务器上2.检查server02服务器网卡3.检查route01上的网卡三、在route01上启动IP包转发四、查看当前两节点互通情况1.查看server01和server02连通状态2.查看…

新手小白可以做什么互联网项目,副业项目应该怎么选择

现在网上的信息这么冗杂&#xff0c;有没有可靠的副业项目呢&#xff1f;怎样才能找到适合自己的副业呢&#xff1f; 说实话&#xff0c;在网上找副业并不难&#xff0c;搜索一下就会出来很多&#xff0c;但新手小白不知道如何选择&#xff0c;导致焦虑&#xff0c;一个重要的…

helm2.0安装及部署

一、helm简介 Helm是Deis (https://deis.com/) 开发的一个用于kubernetes的包管理器。每个包称为一个Chart&#xff0c;一个Chart是一个目录&#xff08;一般情况下会将目录进行打包压缩&#xff0c;形成name-version.tgz格式的单一文件&#xff0c;方便传输和存储&#xff09…

Linux 如何设置代理

安装部署 clash 是一款用 Go 语言开发的软件&#xff0c;所以我可以直接下载预编译的版本进行部署。 下载地址&#xff1a;https://github.com/Dreamacro/clash/releases/download/v1.8.0/clash-linux-amd64-v1.8.0.gz软件的作者提供了多种架构下预编译的二进制文件&#xff0…

67 - 经典问题解析五(指针的判别 构造中的异常)

---- 整理自狄泰软件唐佐林老师课程 1. 问题一 编写程序判断一个变量是不是指针&#xff1f; 1.1 指针的判别 C中仍然支持C语言中的可变参数函数C编译器的 匹配调用 优先级&#xff1a;重载函数 > 函数模板 > 变参函数 #include <iostream> #include <strin…