小程序开发之实现左滑删除功能

▶动态效果图◀

 

▶效果涉及的小程序事件◀

touchstart手指触摸动作开始 
touchmove手指触摸后移动 
touchend手指触摸动作结束

详细介绍参考文档:小程序事件详解

 

▶WXML◀

<!-- 自定义单选/多选/全选实现删除功能 -->
<view class="item-box">
  <view class="items">
    <view wx:for="{{list}}" wx:key="{{index}}" class="item">
      <view class='msg' style="{{item.txtStyle}}" bindtouchstart="touchS" bindtouchmove="touchM" bindtouchend="touchE" data-index="{{index}}">
        <view class="inner txt">{{item.txt}}</view>
        <view class="inner del">
          <span class="draw" data-name="{{item.txt}}" bindtap="tryDriver">试驾</span>
          <span class="delete" data-index="{{index}}" bindtap="delItem">删除</span>
        </view>
      </view>
    </view>
  </view>
</view>

 

布局思路:

    每一行数据包括一段文本和两个操作按钮,布局的时候通过right: -120px;设置按钮不可见,用户滑动行数据的时候,将整个行数据向左移动,从而显示出两个按钮。

 

ForEach的集合list中对象item包括两个属性

item.txt: 文本内容

item.txtStyle : 定义整行数据向左移动的距离

 

▶WXSS◀

.item {
  position: relative;
  border-top: 2rpx solid #eee;
  height: 120rpx;
  line-height: 120rpx;
  overflow: hidden;
}

.inner.txt {
  font-family: Monaco;
  width: 100%;
  z-index: 5;
  padding: 0 10rpx;
  transition: left 0.2s ease-in-out;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.inner.del {
  position: absolute;
  width: 260rpx;
  height: 148rpx;
  top: 1rpx;
  right: -120px;
  color: #fff;
  text-align: center;
  line-height: 110rpx;
}

.msg {
  position: absolute;
  width: 100%;
  height: 150rpx;
  left: 0;
  top: 0;
  z-index: 100;
  background-color: #fff;
}

.draw {
  border-right: 1px solid #fff;
  display: inline-block;
  width: 120rpx;
  height: 115rpx;
  background: #d6cdcd;
}

.delete {
  display: inline-block;
  width: 120rpx;
  height: 115rpx;
  background: #fd9903;
}

 

▶ J S ◀

JS中关于滑动效果的三个函数 touchS 、touchM 、touchE

touchS :当触摸屏上只有一个触摸点时,设置触摸起始点水平方向的位置

touchM:当触摸屏上只有一个触摸点,计算该点滑动的距离,根据滑动的距离大小设置整行的class属性txtStyle,从而达到滑动的效果

touchE:当触摸屏上只有一个触摸点,计算该点滑动的距离,如果滑动距离大于按钮长度的1/2则显示按钮,否则不显示

var app = getApp();
Page({
  data: { 
    btnWidth: 260,   //按钮的宽度单位
    startX: "",      //手指触摸开始滑动的位置
    list: [{         //展示的数据
      txtStyle: "",  //定义行数据向左偏移原始位置的距离
      txt: "试驾车辆_奥迪: 皖B 1567",
    },
      {
        txtStyle: "",
        txt: "试驾车辆_宝马: 陕D 2777",
      },
      {
        txtStyle: "",
        txt: "试驾车辆_上汽: 皖A 6666",
      }]       
  },
  onLoad: function (options) {
    // 页面初始化
    this.initEleWidth();
  },
  touchS: function (e) {
    console.log(e.touches.length);
    if (e.touches.length == 1) { //触摸屏上只有一个触摸点
      this.setData({
        //设置触摸起始点水平方向位置
        //clientX:距离页面可显示区域(屏幕除去导航条)左上角距离,横向为X轴,纵向为Y轴
        startX: e.touches[0].clientX
      });
    }
  },
  touchM: function (e) {
    if (e.touches.length == 1) { // 一个触摸点
      //手指移动时水平方向位置
      var moveX = e.touches[0].clientX;
      //手指起始点位置与移动期间的差值
      var disX = this.data.startX - moveX;
      //按钮
      var btnWidth = this.data.btnWidth;
      var txtStyle = "";
      if (disX == 0 || disX < 0) {//如果移动距离小于等于0,说明向右滑动,文本层位置不变
        txtStyle = "left:0px";
      } else if (disX > 0) {//移动距离大于0,文本层left值等于手指移动距离
        txtStyle = "left:-" + disX + "px";
        if (disX >= btnWidth) {
          //控制手指移动距离最大值为删除按钮的宽度
          txtStyle = "left:-" + btnWidth + "px";
        }      
      }
      //获取手指触摸的是哪一项
      var index = e.currentTarget.dataset.index;
      //设置该项向左偏移的样式,并消除其他项的偏移样式
      var list = this.data.list;
      for (var ix in list) {
        ix == index ? list[ix].txtStyle = txtStyle : list[ix].txtStyle = "";
      }
      //更新列表的状态
      this.setData({
        list: list
      });
    }
  },
  touchE: function (e) {
    if (e.changedTouches.length == 1) { //一个触摸点
      //手指移动结束后水平位置
      var endX = e.changedTouches[0].clientX;
      //触摸开始与结束,手指移动的距离
      var disX = this.data.startX - endX;
      var btnWidth = this.data.btnWidth;
      //如果距离小于删除按钮的1/2,不显示删除按钮
      var txtStyle = disX > btnWidth / 2 ? "left:-" + btnWidth + "px" : "left:0px";
      //获取手指触摸的是哪一项
      var index = e.currentTarget.dataset.index;
      //设置偏移的样式
      var list = this.data.list;
      list[index].txtStyle = txtStyle;
      //更新列表的状态
      this.setData({
        list: list
      });
    }
  },
  //获取元素自适应后的实际宽度
  getEleWidth: function (w) {
    var real = 0;
    try {
      var res = wx.getSystemInfoSync().windowWidth;
      var scale = (750 / 2) / (w / 2);//以宽度750px设计稿做宽度的自适应
      real = Math.floor(res / scale);
      return real;
    } catch (e) {
      return false;
      // Do something when catch error
    }
  },
  initEleWidth: function () {
    var btnWidth = this.getEleWidth(this.data.btnWidth);
    this.setData({
      btnWidth: btnWidth
    });
  },
  //点击删除按钮事件
  delItem: function (e) {
    var that = this;
    //获取列表中要删除项的下标
    var index = e.currentTarget.dataset.index;
    var list = that.data.list;
    wx.showModal({
      title: '提示',
      content: '是否确认试驾',
      success(res) {
        if (res.confirm) {
          //移除列表中下标为index的项
          list.splice(index, 1);
          //更新列表的状态
          that.setData({
            list: list
          });
        }
      }
    })
   
  },
  //点击试驾
  tryDriver: function (e) {
    wx.showModal({
      title: '提示',
      content: '是否确认试驾',
      success(res) {
        if (res.confirm) {
          console.log('开始试驾')
        }
      }
    })
  }
})

 

参考博客:https://www.cnblogs.com/bgwhite/p/9278932.html ,在博主的文章上做了小小的改动

 

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值