博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
小程序:模仿美团商品列表
阅读量:7104 次
发布时间:2019-06-28

本文共 3937 字,大约阅读时间需要 13 分钟。

最近需求是做一个类似外卖软件的商品列表,左边类型标题栏一个滚动区域右边商品栏一个滚动区域这样子,两边的滚动是互相响应的。

搜了一下github,小程序好像还没有人开源出这个轮子来,当然安卓,ios,js这样的也是有的。所以就写了个demo~

实现功能

右边商品栏滚动到不同区域时:

1,左边类型标题栏会自动切换选中,并且滚动到中间位置。

2,最上标题切换。

点击左边标题栏一项时:

1,右边商品栏滚动到响应区域,标题切换。

备注

1,这里我用了wepy框架。其实这根框架没有一点关系,只不过我懒惰费事改回原生而已。wepy对象就相当于原生的wx对象,然后repeat其实就是个循环,没其他了。

2,存在的问题还是有的,虽然处理了,但是还是不清楚为什么会这样。scroll-top属性是不会跟随scroll-view滚动的而改变的,所以要自己手动改变,例如本来默认是0的,当你滑动到最底的时候他的值还是0,所以我每次滚动前先将scroll-top设置成目前值+0.00001(先做一个超级不明显的改变),再做赋值,这样就不会出现不生效的情况,但是不支持同步赋值,例如我先设置为0再设置设置成1,也是不生效的,所以我这里用了setTimeout异步了一下,就生效了。

实现思路

  • 其实就两个事件,一个右边商品栏的滚动事件,一个就是左边标题栏的每一项的点击事件
  • 初始化拿到数据的时候计算高度,距离,添加到每一项。
  • 用的是scroll-view组件 然后通过改变scroll-top属性来控制滚动区域滚动,至于为什么我没有用scroll-into-view,上面说到了目前值+0.00001,scroll-into-view传的是id,试过改成一个不存在的id没结果是不起作用的,所以我还是选择用scroll-top。

实现代码

data

data = {  goodsList: [    {      title: '类型1',      good: ['0-1', '0-2', '0-3']    },    {      title: '类型2',      good: ['1-1', '1-2', '1-3', '1-4']    },    {      title: '类型3',      good: ['2-1', '2-2', '2-3']    },    {      title: '类型4',      good: ['3-1', '3-2', '3-3']    },    {      title: '类型5',      good: ['4-1', '4-2', '4-3']    },    {      title: '类型6',      good: ['4-1', '4-2', '4-3']    },    {      title: '类型7',      good: ['4-1', '4-2', '4-3']    },    {      title: '类型8',      good: ['4-1', '4-2', '4-3']    },    {      title: '类型9',      good: ['4-1', '4-2', '4-3']    },    {      title: '类型9',      good: ['4-1', '4-2', '4-3']    },    {      title: '类型9',      good: ['4-1', '4-2', '4-3']    },    {      title: '类型9',      good: ['4-1', '4-2', '4-3']    },    {      title: '类型9',      good: ['4-1', '4-2', '4-3']    }  ],  inScroll: 0, // 滚动子项id  scrollTop: 0.00001, // 商品栏离顶部距离  typeTop: 0.000001, // 类型导航栏离顶部距离  // 屏幕高度  windowHeight: 0, // 获得可用窗口高度  goodsType: null // 商品栏上面固定的标题}复制代码

  1. methods

methods = {  /**   * 点击左边的标题栏的一项,把那一项的序号传进来就完事了   * @param index   */  toScrollItem (index) {    this.scrollTop = this.scrollTop += 0.00001    setTimeout(() => {      this.scrollTop = this.goodsList[index].top.begin      this.$apply()    })  },  /**   * 这里监听商品栏滚动条   * @param detail   */  handleScroll({detail}) {    // 每次滚动都需要循环匹配,找寻滚动条到达那个区域,匹配到了或者到最后了就停止,是真的蛋疼。    for (let i = 0; i < this.goodsList.length; i += 1) {      // 进入循环了,这个商品列表的数组是经过加工的,在初始化的时候计算了每个种类项区域(top)和左边标题(typeTop)离顶部距离。      let v = this.goodsList[i]      // 如果滚动条与顶部的距离 >= 这一项开头的与顶部的距离 < 这一项结尾与顶部的距离,那么现在正显示的就是这个区域了。      if (detail.scrollTop >= v.top.begin && detail.scrollTop < v.top.end) {        // 记录下现在显示的是第几个区域。        this.inScroll = i        // 位于商品栏区域上面的标题跟着变成现在显示的区域。        this.goodsType = v.title        // 左边标题栏也跟着滚动到,如果可以(看标题栏有多长囖),将对应的区域移到中间。        this.typeTop = v.typeTop        // 匹配到了,并且做完该做的东西就跳出循环,免得他继续匹配。        break      }    }  }}复制代码

onLoad

async onLoad() {  // 制作顶部距离,盒子高度,子项滚动id属性。  let [top, typeTop] = [0, 0]  this.goodsList.map((v, i) => {    // 这个商品栏区域总高度,因为每个子项高度都是固定的,x长度就是他的总高度。    this.goodsList[i].height = (v.good.length * 200 + 30)    // 计算这个商品栏的开头和结尾离头部的距离,就是此区域的位置,用来判断目前显示区域的。    // top就是这个区域开头与滚动区顶部的位置    this.goodsList[i].top = {begin: top, end: top + (v.good.length * 200 + 30)}    // 计算此项商品标题在商品类型标题栏的高度    this.goodsList[i].typeTop = typeTop    // 计算之后这个top就自增一个上一个区域的总高度的单位    top += (v.good.length * 200 + 30)    // 左边标题栏也自增一个固定长度单位,可以改的 ,看样式定义多少    typeTop += 100  })  // 获取屏幕总高度  const {windowHeight} = await wepy.getSystemInfoSync()  this.windowHeight = windowHeight  //  this.goodsType = this.goodsList[0].title}复制代码

view

复制代码

style

复制代码

然后做出来就是这样样子的

各位大佬如果觉得我有什么写的不对的地方或者更有方案的建议,可以私信或者评论告诉我,我这个是比较粗糙的版本,只是一个基本的实现思路,第一次写练练文笔请多包涵。

转载于:https://juejin.im/post/5c3bf6bfe51d451bd166472a

你可能感兴趣的文章
弹出对话框---MessageBox
查看>>
定义的命令不可用的原因及解决办法
查看>>
libevent(十三)evhttp事件处理流程
查看>>
1004. 西西弗斯式的命运——java
查看>>
jquery弹出遮掩层
查看>>
前端基础-CSS
查看>>
14、BigInteger类简介
查看>>
Ubuntu14.04安装CUDA6.5
查看>>
python工程化最佳实践
查看>>
php正则表达式总结
查看>>
Jquery判断数组中是否包含某个元素$.inArray()的用法
查看>>
MyBatis介绍及使用
查看>>
软件版本说明 转
查看>>
最大连续乘积子串
查看>>
***博客系统文章的数据库存储方式
查看>>
linux上ln链接命令详细说明
查看>>
基于OpenCv和swing的图片/视频展示Java实现
查看>>
Android下载图片路径问题
查看>>
内存数组的存储
查看>>
使用BIOS进行键盘输入和磁盘读写01 - 零基础入门学习汇编语言75
查看>>