背景

上篇文章记录了小程序的自定义导航栏的实现过程和小程序根底组件 cover-image 中 应用 fiexd 生效的坑。

前天忽然在qq上看到一个学妹在群里@我问我小程序怎么实现左滑删除,明天正好周末有空,于是就写了这篇文章。

成果展现

实现过程

  • 用小程序根底组件 movable-areamovable-view 搭建视图架子
  • 拿到后盾的商品数据循环展现
  • 左滑展现右侧暗藏的红色删除按钮
  • 点击按钮,通过 dataset 拿到以后索引,删除数组中对应的数据

伪代码:

<block wx:for="{{infoList}}" wx:for-index="index" wx:key="id" wx:for-item="item">  <movable-area >    <movable-view class="item" damping="100" direction="horizontal" out-of-bounds="true" animation="true">      <!-- 滑动删除右边显示信息的盒子 -->      <view></view>      <!-- 左边删除按钮的盒子 -->      <view bindtap="handleDelShop">删除</view>    </movable-view>  </movable-area></block>      // js 代码    // 删除商品处理事件async handleDelShop(e) {    let { index, id } = e.currentTarget.dataset;    let infoList = this.data.cartData.goods;    infoList.splice(index, 1);    this.setData({      [infoList]: infoList,    })},

须要留神的中央

  • 右边显示的区域宽度肯定要设置 100vw,并且加上 overflow: hidden 防止出现x轴方向的滑动条,在外层的整个盒子加上 box-sizing: border-box;
  • 给根底组件设置高度
    movable-areamovable-view 是有默认的高度的,必须设置这两个根底组件的高度,如果不设置的话,就算外面的盒子有固定高度,也不会失效的,所以特地肯定要留神,设置固定高度,在写代码前就要算好外面的盒子的高度,如果因为数据不确定,依据不同数据展现不同高度的话,能够用条件判断,设置不同高度。

优化

为了用户体验更好,我做了一下优化,相似这种成果:

(因为在网吧写的文章,没有动图素材,就用了他人的动态图,遗记起源了,不过释怀哈,代码实现的成果是一样的!有晓得动静起源的能够通知我,前面我加上。)

做了以下优化:

  • 判断高低滑动还是左右滑动,高低滑动则还原所有项的样子(暗藏所有项的删除按钮)。
  • 左滑另一个项时,其余项的删除按钮全暗藏,只显示一个项的删除。
  • 左滑间隔超过 20px 就主动滑到能显示残缺的删除按钮的样子。小于 20px 则复原原来的样子(暗藏删除按钮)

ok,废话不多说了看具体代码:

<block wx:for="{{infoList}}" wx:for-index="index" wx:key="id" wx:for-item="item">  <movable-area >    <movable-view bindtouchstart="touchStart" data-index="{{index}}" bindtouchend="touchend" class="item" x="{{shopInfo.x}}" y="{{shopInfo.y}}" damping="100" direction="horizontal" out-of-bounds="true" animation="true">      <!-- 滑动删除右边显示信息的盒子 -->      <view></view>      <!-- 左边删除按钮的盒子 -->      <view bindtap="handleDelShop">删除</view>    </movable-view>  </movable-area></block>      // js 代码 data 里的变量:data: {    currentTouche: {      x: 0,      y: 0    },    offset: 20,},    // 删除商品处理事件async handleDelShop(e) {    let { index, id } = e.currentTarget.dataset;    let infoList = this.data.cartData.goods;    infoList.splice(index, 1);    this.setData({      [infoList]: infoList,    })},  touchStart(e) {    let { clientX, clientY } = e.changedTouches[0];    let { index } = e.currentTarget.dataset;    // 重置列表除以后操作的项之外的所有项在x方向的偏移量    let newCartData = this.data.infoList.map((v, idx) => {      if (index != idx) {        v.x = '';        v.y = '';      }      return v;    })    this.setData({      infoList: newCartData    })    this.setData({      currentTouche: {        x: clientX,        y: clientY      }    })  },  touchend(e) {    let { clientX, clientY } = e.changedTouches[0];    let { index } = e.currentTarget.dataset;    // 判断是上下滑还是左右滑    if (Math.abs(clientY - this.data.currentTouche.y) < Math.abs(clientX - this.data.currentTouche.x)) {  // 左右滑动      // 判断是左滑还是右滑      if (clientX >= this.data.currentTouche.x) {  // 右滑        this.setData({          [`infoList[${index}].x`]: 0        })      } else {   //左滑        if (this.data.currentTouche.x - clientX >= this.data.offset) {          this.setData({            [`infoList[${index}].x`]: -rpxTopx(164)          })        } else {          this.setData({            [`infoList[${index}].x`]: 0          })        }      }    } else {  // 高低滑动      // 重置数据      this.setData({        [`infoList[${index}].x`]: 0      })    }    this.setData({      currentTouche: {        x: clientX,        y: clientY      }    })  },

代码解释:通过 touchStart 和 touchEnd 事件能够晓得滑动开始时的地位和滑动完结后的地位。


获取 changedTouches[0] 触摸点的地位信息

changedTouches 里一项的属性

  1. 先判断高低滑动的间隔是否大于左右滑动的间隔,如果大于则为高低滑动并且重置地位数据,否则为左右滑动,
  2. 如果为左右滑动时判断左滑还是右滑,左滑时:左滑间隔超过 20px 就主动滑到能显示残缺的删除按钮的样子。小于 20px 则复原原来的样子(暗藏删除按钮)。如果右滑时重置 x 轴方向的地位数据(让删除按钮暗藏,复原到原来的样子)。

总结

性能实现起来很简略,然而刚开始因为工夫不叫紧迫,就做的不叫匆忙,后就有须要优化用户体验的中央,比方左滑挪动的间隔在 20px 以内松手后应该反弹回原来的地位,超过 20px 松手后应该主动滑动到百分之100。

因为小程序对用户来说比拟不便,所以个别的toC的我的项目都会有小程序端。总之心愿这边文章对小伙伴们有作用!感觉还不错的话能够点赞珍藏起来,以备不时之需(说不定下次公司就让你写这种小程序相似的需要了呢)

写在最初

我是 AndyHu,目前临时是一枚前端搬砖工程师。

文中如有谬误,欢送在评论区斧正,如果这篇文章帮到了你,欢送点赞和关注呀

未经许可禁止转载

speak less,do more.