微信小程序的无限瀑布流写法

这篇具有很好参考价值的文章主要介绍了微信小程序的无限瀑布流写法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

微信小程序的无限瀑布流实现总算做完了,换了好几种方法,过程中出现了各种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:else
          class="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条不会触发onload
          const { 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;
}

微信小程序的无限瀑布流写法,微信小程序,小程序,前端,javascript文章来源地址https://www.toymoban.com/news/detail-730143.html

到了这里,关于微信小程序的无限瀑布流写法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 微信小程序瀑布流和虚拟列表

    首先声明虽然本篇是写的微信小程序的案例,但是也可用于H5,思路是想通的,只是有些api的差异,最后会贴代码片段 虚拟列表 一般在做长列表优化时,特别是面试时,虚拟列表就是个高频词。这个名词听起来很高级,其实原理很简单 虚拟列表就是将需要渲染的数组数据改

    2024年02月14日
    浏览(36)
  • 微信小程序css实现瀑布流布局

    废话不多说 直接上代码 博客地址:BULINGBULING

    2024年02月13日
    浏览(43)
  • 微信小程序实现吸顶、网格、瀑布流布局

    微信小程序开发通常是在webview模式下编写,但是对小程序的渲染性能有一定的追求,就需要使用Skyline模式进行渲染,同时在这种模式下有也有一些特殊的组件,可以轻松的实现想要的效果,本文将介绍在Skyline模式下如何实现吸顶、网格、瀑布流布局。 以下是具体的实现:

    2024年02月22日
    浏览(59)
  • 微信小程序实现瀑布流布局(方式一)

    根据奇数列和偶数列区分左边和右边数据 设置width固定,mode=“widthFix” 适用于:左右两列的高度相差不是很大

    2024年02月12日
    浏览(37)
  • uniapp 瀑布流 (APP+H5+微信小程序)

    WaterfallsFlow.vue waterfall.vue

    2024年02月15日
    浏览(56)
  • 微信小程序上传图片写法

    小程序上传图片需要用到小程序API中的wx.uploadFile()方法。以下是一个基本的示例代码: 在这个示例代码中,首先使用wx.chooseImage()方法让用户选择一张图片,然后通过wx.uploadFile()方法将选中的图片上传到指定的接口地址。在上传成功后,我们可以在success回调函数中获

    2024年02月11日
    浏览(75)
  • 微信小程序原生写法传递参数

        data-xxx   自定义参数名  ,接收参数:方法(变量名)  如果需要传递多个,可以写多个data-[参数]的方式进行传递 多个参数写法 data-a ,data-b, 接收参数 :方法(变量名)    建议采用全小写命名,简短短拼~

    2024年02月09日
    浏览(55)
  • 微信小程序animation动画,微信小程序animation动画无限循环播放

    需求是酱紫的: 页面顶部的喇叭通知,内容不固定,宽度不固定,就是做走马灯(轮播)效果,从左到右的走马灯(轮播),每播放一遍暂停 1500ms ~ 2000ms 刚开始想的是 css 的 position: relative + animation,如果宽度固定还好说,宽度不固定,用百分比的话,想象很美好,现实很

    2024年02月13日
    浏览(57)
  • 微信小程序原生写法——24小时时间选择器组件

    使用picker-view来封装成的一个时间选择器 开始时间是当前时间的一个小时之后,秒默认是0秒 可能还有一些情况未处理,后续发现再更新 js文件 第一版:略繁琐 第二版js文件:根据当前时间的时间戳A与24小时之后的时间戳B两者来进行处理获取对应的列表 json文件 wxml文件 wxs

    2024年02月04日
    浏览(57)
  • 原生微信小程序自定义picker多列选择器:picker写法用法

    前言:                    最近用原生微信小程序写法写医疗相关项目微信小程序,在编辑个人资料的时候,需要很多选择器,比如城市地区选择器,职业职称选择器,科室选择器,学校选择器,学历选择器,年份日期选择器........           总之用到的地方比较多

    2024年02月06日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包