微信小程序的无限瀑布流写法
微信小程序的无限瀑布流实现总算做完了,换了好几种方法,过程中出现了各种BUG。
首先官方有瀑布流的插件(Skyline /grid-view),不是原生的我就不想引入,因为我的方块流页面已经搭好了,引入说不定就要涉及样式的修改、代码量的增大等麻烦问题。
H5我虽然也做了瀑布流,但是是用绝对定位来做的,性能消耗有点大。所以小程序这边就是想把原本flex固定宽高的改成两列。(纯CSS就不要想了,根本不可能实现,虽然也查到了新的css瀑布流规则,但绝大部分浏览器不支持也是白搭。)
方案一:
const query = wx.createSelectorQuery().in(this);query.select(`.desc-${index}`).boundingClientRect((res) => {}).exec();
原本显示的数据先做隐藏,之后利用boundingClientRect来获取隐藏块的高度,再计算对比高度看应该放入list1还是list2中。
这样做会出现两个问题,第一,新增列会明显抖动,因为image我用了mode="widthFix",加载页面跳一下还好,无限瀑布流是要一直可以下拉加载的,就会导致每次新图出来都要跳一下,体验很差……
即使第一个问题我可以缓存高度,替换为aspectFill解决。但第二个问题是,它加载越多,异步延迟就越大,会导致后面的高度根本获取不到而无法正常排版(大概超过80条左右?)……
方案二:
使用wx.getImageInfo来代替获取图片高度,但这样会出现一个明显的问题,就是每次图片的请求是翻倍的,图片本身就加载请求了一次,现在还多用接口请求了一次,这样做太消耗性能了……
另外要注意的是,我的文字其实也是不定高度的,所以不能只对比图片,还得把图片以外的因素都加进来才行。
方案三:
隐藏块使用bindload获取图片高度。这样既避免了方案一中后续获取不到高度,又使得图片不需要二次请求。于是顺着这个思路走,最终解决了这个浪费了我整整一天工作日的瀑布流问题。
index.wxml
<template name="card"><navigator class="recommend-card" url="/pages/trade/detail/index?id={{item.id}}"><view class="recommend-top"><image wx:if="{{item.height}}"class="recommend-img"src="{{ item.pic }}"mode="aspectFill"style="height: {{item.height}}rpx;" /><image wx:elseclass="recommend-img"src="{{ item.pic }}"data-index="{{index}}"bindload="imgLoad"data-title="{{item.title}}"mode="widthFix" /></view><view class="aui-padded-10 recommend-bottom"><view class="aui-font-size-14 recommend-title">{{item.title}}</view><view class="aui-font-size-12 c9 recommend-position"><image alt="地点" class="position-img" src="{{locUrl}}/svg/trade-position.svg" /><view class="no-wrap">{{item.province}} {{item.city}}</view></view></view></navigator>
</template>
<view class="recommend-list"><template is="card" wx:for="{{tradeList}}" wx:key="index" data="{{item, locUrl, index}}"></template>
</view>
<view class="flex-b"><view><template is="card" wx:for="{{list1}}" wx:key="index" data="{{item, locUrl, index}}"></template></view><view><template is="card" wx:for="{{list2}}" wx:key="index" data="{{item, locUrl, index}}"></template></view>
</view>
index.js
import { dealTradePic } from "~/utils/trade";Component({options: {addGlobalClass: true,},properties: {goodsList: {type: Array,value: [],observer(goodsList) {const tradeList = dealTradePic(goodsList);const obj = { tradeList };if (tradeList.length === 10) {// 因为没有置0处理,重新加载时前10条不会触发onloadconst { list1, list2, bufferH1, bufferH2 } = this.data;obj.list1 = list1.slice(0, 10);obj.list2 = list2.slice(0, 10);obj.h1 = bufferH1;obj.h2 = bufferH2;}this.setData(obj);},}},data: {locUrl: getApp().locUrl,tradeList: [],h1: 0,h2: 0,bufferH1: 0,bufferH2: 0,list1: [],list2: [],count: 0,},methods: {imgLoad(e) {const { width, height } = e.detail;const { index, title } = e.currentTarget.dataset;const { tradeList, list1, list2, h1, h2 } = this.data;// 高度比例切换let h = 340 * height / width;h = h > 480 ? 480 : h;tradeList[index].height = h;// 增加文字与其他高度const word = title.replace(/[^\x00-\xff]/g, "aa").length;const wh = parseFloat((h + (word > 22 ? 38 : 0)).toFixed(2)) + 150;if (h1 <= h2) {list1.push(tradeList[index]);this.data.h1 = parseFloat(h1.toFixed(2)) + wh;} else {list2.push(tradeList[index]);this.data.h2 = parseFloat(h2.toFixed(2)) + wh;}// 初始高度记录,用于清空this.data.count++;if (this.data.count === 10) {this.data.bufferH1 = this.data.h1;this.data.bufferH2 = this.data.h2;}this.setData({ list1, list2 });}}
});
index.wxss
.recommend-list {display: flex;flex-flow: row wrap;justify-content: space-between;padding: 0;height: 0;overflow: hidden;
}.recommend-card {box-sizing: border-box;font-size: 24rpx;border-bottom: none;width: 342rpx;margin-bottom: var(--gap);
}.recommend-top {width: 340rpx;
}.recommend-img {display: block;width: 100%;height: 100%;border-radius: 16rpx 16rpx 0 0;overflow: hidden;
}.recommend-title {font-size: 28rpx;overflow: hidden;-o-text-overflow: ellipsis;text-overflow: ellipsis;display: -webkit-box;-webkit-line-clamp: 2;-webkit-box-orient: vertical;
}.recommend-position {display: flex;align-items: center;margin-top: 12rpx;
}.recommend-bottom {background-color: white;border-radius: 0 0 16rpx 16rpx;
}
相关文章:
微信小程序的无限瀑布流写法
微信小程序的无限瀑布流实现总算做完了,换了好几种方法,过程中出现了各种BUG。 首先官方有瀑布流的插件(Skyline /grid-view),不是原生的我就不想引入,因为我的方块流页面已经搭好了,引入说不定…...
前有CAP理论,后有BASE理论,分布式系统理论基石
🧑💻作者名称:DaenCode 🎤作者简介:CSDN实力新星,后端开发两年经验,曾担任甲方技术代表,业余独自创办智源恩创网络科技工作室。会点点Java相关技术栈、帆软报表、低代码平台快速开…...
HTTP、TCP、SOCKET三者之间区别和原理
7层网络模型 网络在世界范围内实现互联的标准框架 7层为理想模型,一般实际运用没有7层 详细内容 HTTP属于7层应用层 BSD socket属于5层会话层 TCP/IP属于4成传输层 TCP/IP协议 三次握手 笔者解析: 第一次握手:实现第一步需要客户端主动…...
flutter项目中常用第三方模块
flutter项目中常用第三方模块 持续更新中序言关于第三方模块安装flutter_native_splash使用方式模块配置 flutter_localizations模块配置使用方式 get_storage模块配置使用方式 get模块配置使用方式 持续更新中 序言 本章介绍项目中常用第三方模块,方便快速构建项目…...
Android 混淆使用及其字典混淆(Proguard)
1.使用背景 ProGuard能够通过压缩、优化、混淆、预检等操作,检测并删除未使用的类,字段,方法和属性,分析和优化字节码,使用简短无意义的名称来重命名类,字段和方法。从而使代码更小、更高效、更难进行逆向工程。 Android代码混淆…...
laravel 阿里云短信发送
示例 一、安装 安装:composer require mrgoon/aliyun-sms dev-master 二、打开config/app.php,添加配置代码 1、‘providers’ 配置组下添加 Mrgoon\Aliyunsms\AliyunsmsServiceProvider::class, 2、‘aliases’ 配置组下添加 Aliyunsms>Mrgoon…...
算法----LRU缓存机制
题目 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类: LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存 int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返…...
基于springboot+vue的旅游系统(前后端分离)
博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容:毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…...
什么是堆栈和队列?如何实现它们?
堆栈(Stack)和队列(Queue)是两种常见的线性数据结构,用于组织和管理数据。它们分别具有不同的特点和用途。本文将详细解释堆栈和队列的概念、特点以及如何实现它们。 堆栈(Stack) 什么是堆栈&…...
编译器自动生成的构造函数
背景 作为一个C小白,最近在看深度解析对象模型的时候,发现一个很久以来的认知错误:编译器会为没有定义构造函数的class生成一个默认构造函数。其实这个观点是错误的,编译器只会在四种情况下生成。 相关知识 一定要明确一个事情…...
SpringSecurity - 认证与授权、自定义失败处理、跨域问题、认证成功/失败处理器
SpringSecurity 文章目录 SpringSecurity一、 简介二、快速入门2.1 maven坐标2.2 访问请求 三、认证与授权3.1 认证3.1.1 登录检验流程3.1.2 SpringSecurity 完整流程3.1.3 认证流程详解3.1.4 校验3.1.5 要解决的问题3.1.6 准备工作3.1.7 实现3.1.7.1 数据库校验用户3.1.7.1.1 …...
自定义映射resultMap
自定义映射resultMap 自定义映射resultMap 自定义映射resultMapresultMap处理字段和属性的映射关系字段名和属性名不一致的情况,如何处理映射关系?1、为查询的字段设置别名,和属性名保持一致2、核心配置文件(mybatis-config.xml)中设置一个全局配置3、使…...
Android修行手册 - Android Studio去掉方法参数提示、变量类型提示、方法引用Usage提示
点击跳转>Unity3D特效百例点击跳转>案例项目实战源码点击跳转>游戏脚本-辅助自动化点击跳转>Android控件全解手册点击跳转>Scratch编程案例点击跳转>软考全系列 👉关于作者 专注于Android/Unity和各种游戏开发技巧,以及各种资源分享&…...
【车载开发系列】ECU Application Software程序刷新步骤
【车载开发系列】ECU Application Software程序刷新步骤 ECU Application Software程序刷新步骤 【车载开发系列】ECU Application Software程序刷新步骤一. Boot Software(引导软件)1)boot manager(启动管理器)2&…...
inject和provide的使用
官网介绍用法 V2.2.0 新增的方法 类型 provide:Object | () > Object inject:Array<string> | { [key: string]: string | Symbol | Object }介绍 这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖ÿ…...
2023年中国研究生数学建模竞赛D题
一、背景介绍 2021年9月22日,中共中央国务院正式发布《关于完整准确全面贯彻新发展理念做好碳达峰碳中和工作的意见》(以下简称《意见》),明确了中国双碳行动的顶层设计。 我国是世界上最大的发展中国家,为实现中华民…...
Unity制作曲线进度条
unity制作曲线进度条 大家好,我是阿赵。 在使用Unity引擎做进度条的时候,有时会遇到一个问题,如果进度条不是简单的横向、纵向或者圆形,而是任意的不规则形状,那该怎么办呢?比如这样的: 一…...
面试:C++ 11 智能指针
查询内存泄露方法 啥是内存泄露 内存泄露在维基百科中的解释如下: 在计算机科学中,内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误&…...
设计模式——3. 抽象工厂模式
1. 说明 抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供了一种创建一组相关或依赖对象的方式,而无需指定它们的具体类。抽象工厂模式是工厂模式的扩展,它关注于创建一组相关的对象家族,而不仅仅是一个单一的对象。 抽象工厂模式通常涉及以下几个角…...
vscode 无法使用 compilerPath“D:.../bin/arm-none-eabi-g++.exe”解析配置。
最近在使用vscode搭建ODrive STM32开发环境,依次安装了以下内容: 1.Python3: 用于运行工程构建脚本 2.ST-Link/V2 Drivers: STLink/v2编程器的驱动 3.Visual Studio Code: 轻量级但功能强大的源代码编辑器 …...
Vue.js入门模板语法[上] 及Vue.js实现购物车---详细讲解
前言 前面我们学习了Vue的基础入门,接下来我们学习有关Vue的模板语法,学习Vue语法能提高我们的前端开发效率 Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。所有 Vue.js 的模板都是合法的 HTML &a…...
windows下gvim的配置
一、vim配置文件 "查看自己的vimrc所在的目录 "在命令模式下 :echo $MYVIMRC"打开自己的vimrc文件 "在命令模式下 :e $MYVIMRC 二、排版 "查看自己当前的字体及大小 "在命令模式下 :set guifont?"设置默认的字体为仿宋_GB2312ÿ…...
基于复旦微的FMQL45T900全国产化ARM开发开发套件(核心板+底板)
TES745D是我司自主研制的一款基于上海复旦微电子FMQL45T900的全国产化ARM核心板(模块)。该核心板将复旦微的FMQL45T900(与XILINX的XC7Z045-2FFG900I兼容)的最小系统集成在了一个87*117mm的核心板上,可以作为一个核心模…...
Leetcode Top100(23)环形链表
给你一个链表的头节点 head ,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索…...
线性代数基础-行列式
一、行列式之前的概念 1.全排列: 把n个不同的元素排成一列,称为n个元素的全排列,简称排列 (实际上就是我们所说的排列组合,符号是A,arrange) 2.标准序列: 前一项均小于后一项的序列…...
RT-Thread(学习)
RT-Thread是一款完全由国内团队开发维护的嵌入式实时操作系统(RTOS),具有完全的自主知识产权。经过16个年头的沉淀,伴随着物联网的兴起,它正演变成一个功能强大、组件丰富的物联网操作系统。 RT-Thread概述 RT-Threa…...
【MySQL】 MySQL 死锁问题分析优化器特性及优化方案
MySQL 死锁问题分析优化器特性及解决方案 MySQL 锁机制介绍 1、MySQL常用存储引擎的锁机制 MyISAM和MEMORY采用表级锁(table-level locking) BDB采用页面锁(page-level locking)或表级锁,默认为页面锁 InnoDB支持行级锁(row-level locking)和表级锁,默认为行级…...
【C++面向对象侯捷】8.栈,堆和内存管理
文章目录 栈,堆stack object的生命周期static local object的生命周期global object的生命周期heap objects 的生命期new:先分配memory,再调用构造函数delete: 先调用析构函数,再释放 memory动态分配所得的内存块,in V…...
在比特币上使用可检索性证明支付存储费用
我们为用户开发了一种为云存储付费的新方法。 与亚马逊的 S3 等传统云存储相比,用户不必信任服务器。 我们使用比特币智能合约来确保支付取决于服务器的可检索性证明 (PoR),该证明只能在数据仍然可用且需要时可以检索的情况下生成。 可检索性证明 (PoR)…...
使用SSE(Server-Sent Events)实现服务端给客户端发消息
首先是客户端,看着比较简单。但实际应用中可能要比这复杂,因为默认sse只支持get请求,而且没法携带header。所以如果默认的方法达不到需求的话可能需要额外实现,当然也可以引用第三方库,比如rangermauve/fetch-event-so…...
一个网站为什么做的不好看/武汉十大技能培训机构
商业产品代工的模式本质上是一种品牌营销的模式、 比说看到某些产品很好卖,自己有资本 当然自己已经有很好卖的几样产品就更好办了,看看客户的行为,讲好卖的产品进行代工,进行在线销售,具有成长性增大倾斜力度…...
o2o网站建设哪家好/googleseo优化
1.准备两个个全新的tomcat8,用来作为sso单点登录的客户端,如下: 2.修改server.xml文件(因为考虑到端口冲突,所以将里面的端口全部改掉) 需要框架源码的朋友可以看我个人简介联系我,推荐源码 其中apache-tomcat-clien…...
一起做英语网站/广告推广赚钱在哪接
WCHAR buffer[1024]; SecureZeroMemory(buffer, 1024); wstring str L"hello word" wsprintfW(buffer, L"%s", str.c_str()); 需要注意的是 第一个参数 是buffer 最大为 1024...
律师做几个网站/网站google搜索优化
#!/bin/bash #自动备份grafana数据库并上传到云盘 NOWDATEdate %Y-%m-%d YUNPAN_USERxxxx YUNPAN_PASSWDXXXXXXXXXX YUNPAN_SERVERhttps://yunpan.x.com/remote.php/webdav YUNPAN_DIRx/backup/grafana #建立备份基本目录环境 BACKUPDIR/x/data/backup/grafana [ -d ${BACKUPDI…...
生活馆网站开发背景/百度答主中心入口
来源于问题:OpenStack ironic组件如何管理物理机?Ironic是OpenStack裸机管理服务(baremetal as service),裸机即没有安装任何操作系统的物理服务器。虽然ironic支持standalone部署模式,但通常会协同OpenSta…...
seo网站关键词优化方法/推广文案范例
前言:本人是java后端开发,用到的linux命令不是很多,只展示一些常用的命令,方便在工作中快速使用。一些命令的扩展及详细参数,请小伙伴们自行百度。内容有错误或者有异议的欢迎批评指正。用户&用户组创建用户&#…...