微信小程序滑动删除(真机测试下可用),通过css3 transform实现

刚接触微信小程序不久,在做的项目是个微商城. 其中购物车中需要用到滑动删除功能. 原本在其他平台上利用JS操作DOM计算坐标即可完成,但是小程序的bindtouchmouve,bindtouchend和bindtouchstart事件会冒泡到父级控件,在真机测试中会导致整屏都触发自定义的滑动事件,真个界面都成了万花筒. 如果使用catchtouchmove,catouchend和catchstart. 是可以防止冒泡. 左右也可以正常滑动.但是不仅仅是小程序的横向scroll事件,小程序的纵向scroll事件也会无法触发. 也就是会导致当前页面无法上下滑动. 

我试过用scroll-view控件, 在小程序官方文档中说明scroll-x="false"能禁止x轴滚动. 实际上不管在真机还是微信开发者中都无法起作用. 后来经过多方实验,发现只要滑动模块超过当前屏幕可视宽度,bindtouchmove就会冒泡进而触发整屏滑动,即使删除按钮只是用绝对定位固定在右侧也不行, 例如下图windowWidth为414px, 产品Item宽也是414px,但是加上删除按钮就超出了414px. 滑动时就会触发整屏滑动.

苹果小程序 ios惯性滑动 导航栏 小程序滑动 touch_ico

实在没有办法,后来想到Css3里面的transform变换也可以实现移动的效果,而且移动的距离是不是不计入模块的宽度呢?首先先用删除按钮做测试:

把删除按钮用绝对定位定在Item内右侧,然后利用transform平移到item外右侧. 用真机测试,果然左右滑动不会再触发整个View的滑动了.

苹果小程序 ios惯性滑动 导航栏 小程序滑动 touch_苹果小程序 ios惯性滑动 导航栏_02

 

1  .item .btn-del{
 2   position: absolute;
 3   display: flex;
 4   top:0px;
 5   right:0px;
 6   color: #fff;
 7   background: #fd4346;
 8   height: 100%;
 9   border-radius: 0px;
10   border: none;
11   align-items: center;
12   transform:translate(64px,0);
13   -ms-transform:translate(64px,0);
14   -moz-transform:translate(64px,0);
15   -webkit-transform:translate(64px,0);
16   -o-transform:translate(64px,0);
17 }

 接下来很简单只要把item也利用transform跟随用户手势左右平移即可. 计算用户平移距离和平常一样,我写的比较粗糙,随便一看,

WXML:

<view class="item" data-matindex="{{matIndex}}"
      bindtouchend="touchEndToDel" bindtouchstart="touchStartToDel" bindtouchmove="touchMoveToDel"
      style="webkit-transform:translate({{matItem.moveLeft}}px,0);-webkit-transform:translate({{matItem.moveLeft}}px,0);"
      wx:for="{{matList}}" wx:for-item="matItem" wx:for-index="matIndex" wx:key="skuguid">
 
      <view class="shop-image" >
        <icon wx:if="{{matItem.selected}}" type="success" size="20" color="#2da4e6"  class="my-check"/>
        <icon wx:else type="circle" size="20"  class="my-check"/>
        <image src="{{matItem.imageaddress}}" style="width:180rpx;height:180rpx;"></image>
      </view>     
      <view class="shop-title" bindtap="tapBackDelBtn"data-matindex="{{matIndex}}">
       <text>{{matItem.matname}}</text>  
        <view class="h2 num" wx:if="{{mat.isEdit}}">  
          <view class="flex flex-wrap" >
            <view bindtap="minusNum" data-matindex="{{matIndex}}" class="flex-item">-</view>
            <view class="flex-item">
              <input type="text" value="{{matItem.digit}}"/>
            </view>
            <view bindtap="plusNum" data-matindex="{{matIndex}}" class="flex-item">+</view>        
            </view>
          </view>
        <view class="price">{{matItem.showprice}}</view>
      </view>
      <view class="shop-price" >
        <view></view>
        <view>x{{matItem.digit}}</view>   
     </view>
     <!-- 弹出按钮-删除 -->
       <button bindtap="removeSingle" wx:if="{{!mat.isEdit }}" data-matindex="{{matIndex}}" class="btn-del"  >删除</button>   
    </view> 
  </view>
var moveXList = [0, 0]//X轴移动的距离
  /**
   * 轻触回收指定删除按钮
   */
  tapBackDelBtn:function(e){var matIndex = e.currentTarget.dataset.matindex
    that.backDelBtn(matIndex)
  },
  /**
   * 收回弹出删除按钮
   * matIndex:skuBody下标
   * 如果不传表示全部收回
   */
  backDelBtn:function(matIndex){
    if (!vpUtilService.vpIsNull(matIndex)){
      that.data.matList.forEach(function(item,index){
        item.moveLeft = 0
      })
    } else {
          that.data.matList[matIndex].moveLeft = 0
    }
    that.setData({ matList: that.data.matList})
  },
  /**
   * bindtouchmove
   */
  touchMoveToDel:function(e){
    if (e.touches.length != 1 ){return}
    if (moveXList[1] == 0){
      moveXList.shift()
      moveXList.push(e.touches[0].clientX)
      return
    }var matIndex = e.currentTarget.dataset.matindex
var moveLeft = that.data.matList[matIndex].moveLeft
    if ((moveLeft<=0) || (moveLeft>-64)){//移动范围在 -64px~0之间
      var dis = moveXList[1] - moveXList[0]
      moveLeft = parseInt(moveLeft?moveLeft:0) + parseInt(dis)
      moveLeft = moveLeft < -64? -64: moveLeft
      moveLeft = moveLeft > 0 ? 0 : moveLeft
      moveXList.shift()
      moveXList.push(e.touches[0].clientX)
      that.data.matList[matIndex].moveLeft = moveLeft
      that.setData({ matList: that.data.matList})
    }
    
  },
  /**
  * bindtouchend
  */
  touchEndToDel: function (e) {
var matIndex = e.currentTarget.dataset.matindex
var moveLeft = that.data.matList[matIndex].moveLeft
    if(moveLeft<-32){//移动超过一半的距离,弹出删除按钮
      that.data.matList[matIndex].moveLeft = -64
    }else{//小于一半的距离,收回
      that.data.matList[matIndex].moveLeft = 0
    }
    that.setData({ matList: that.data.matList})
  },
  /**
  * bindtouchstart
  */
  touchStartToDel: function (e) {
    moveXList = [0,0]
  },