小程序開發之實現左滑刪除功能

▶動態效果圖◀

 

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

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 ,在博主的文章上做了小小的改動

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章