小程序里实现左滑动操作

1、wxml 文件

<view class="oper-list">
  <view class="search-input">
    <input placeholder="请输入账号" type="text" confirm-type="search" bindinput="saveKeyword" bindconfirm="queryAdminList" />
    <text class="iconfont icon-chaxun1 icon-query"></text>
  </view>
  <view class="admin-add" bindtap="toAddAdmin">
    <image src="../../../image/add-admin.png" />
  </view>
</view>
<view wx:for="{{role_list}}" wx:for-item="role" wx:key="number" wx:if="{{role.number.length>0}}">

  <view class="role-item-name">
    {{role.name}}
  </view>
  <view wx:if="{{role.number==item.role}}" class="touch-item {{item.isTouchMove ? 'touch-move-active' : ''}}" data-index="{{item.id}}" wx:for="{{show_admin_list}}" wx:key="id">
    <view class="content">
      <view style="{{item.txtStyle}}" class='item' data-index='{{item.id}}' bindtouchstart="touchstart" bindtouchmove="touchmove" bindtouchend="touchE">
        <view class="admin-info">
          <view class="head-pic" bindtap="toAdminInfo" data-admin-no="{{item.clerk_no}}">
            <image src="{{item.head_pic?item.head_pic:default_head_pic}}" />
          </view>
          <view class="role-info" bindtap="toAdminInfo" data-admin-no="{{item.clerk_no}}">
            <view class="admin-info-name">
              {{item.clerk_name}} {{item.clerk_no}}
            </view>
            <view class="role-info-name">
              {{item.role_name}}
            </view>
          </view>
          <view class="role-oper" wx:if="{{item.openid.length>0}}" bindtap="toAdminInfo" data-admin-no="{{item.clerk_no}}">
            <view class="admin-phoneno">
              {{item.phone_no}}
            </view>
            <view class="role-oper-btn">
              已绑定
            </view>
          </view>
          <view class="role-oper" wx:else bindtap="bindAdmin" data-admin-no="{{item.clerk_no}}" data-admin-pwd="{{item.clerk_pwd}}">
            <view class="share-pic">
              <image src="../../../image/share.png"></image>
              <view class="share-txt">
                分享
              </view>
            </view>

          </view>
        </view>
      </view>
    </view>
    <view class="del">
      <view data-admin-no="{{item.clerk_no}}" data-openid="{{item.openid}}" data-id="{{item.id}}" catchtap="operAdmin" data-oper-type="unbind" data-index="{{item.id}}" class="untying">解绑</view>
      <view class='delete' data-admin-no="{{item.clerk_no}}" data-id="{{item.id}}" data-oper-type="delete" catchtap="operAdmin" data-index="{{item.id}}">删除</view>

    </view>

  </view>
</view>

<view class="admin-count">
  {{show_admin_list.length}}个账号
</view>

2、wxss 文件

.touch-item {
  display: flex;
  justify-content: space-between;
   100%;
  overflow: hidden;
  background: rgba(255, 255, 255, 1);
  opacity: 1;
}

.content {
   100%;
  margin-right: 0;
  -webkit-transition: all 0.4s;
  transition: all 0.4s;
  -webkit-transform: translateX(120px);
  transform: translateX(120px);
  margin-left: -120px;
}

.del {
   120px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: #fff;
  -webkit-transition: all 0.4s;
  transition: all 0.4s;
  font-size: 35rpx;
  -webkit-transform: translateX(180px);
  transform: translateX(180px);
}

.del .delete {
  background: red;
  display: flex;
  align-items: center;
  justify-content: center;
   50%;
  height: 100%;
}

.del .untying {
  background: orange;
  display: flex;
  align-items: center;
  justify-content: center;
   50%;
  height: 100%;
}

.touch-move-active .content, .touch-move-active .del {
  -webkit-transform: translateX(0);
  transform: translateX(0);
}

page {
  background: #fff;
}

.oper-list {
   100%;
  display: flex;
  display: -webkit-flex;
  margin-top: 10px;
  margin-bottom: 10px;
  /* position: fixed;
  top: 10px;
  left: 2%; */
}

.search-input {
   84%;
  height: 40px;
  line-height: 40px;
  margin-left: 2%;
}

.search-input input {
  height: 30px;
  line-height: 30px;
  padding: 5px;
  border: 1rpx solid #eee;
  vertical-align: middle;
  border-radius: 30px;
  background: #f5f5f5;
}

.admin-add {
  height: 40px;
  line-height: 40px;
  text-align: center;
   14%;
}

.admin-add image {
   30px;
  height: 30px;
  padding: 5px;
}

.admin-list {
   100%;
  margin-top: 10px;
}

.admin-info {
  display: -webkit-flex;
  height: 60px;
  border-bottom: 1px solid #eee;
  font-size: 14px;
}

/**
内容超出显示 ...
*/

.admin-info-name {
  height: 25px;
  line-height: 25px;
  color: #7a7d88;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.role-info-name {
  height: 25px;
  line-height: 25px;
  color: #7a7d88;
}

.admin-phoneno {
  height: 25px;
  line-height: 25px;
}

.role-oper-btn {
  height: 25px;
  line-height: 25px;
}

.head-pic {
   80px;
  padding: 5px 0px 5px 10px;
}

.head-pic image {
   50px;
  height: 50px;
  border-radius: 10px;
}

.role-info {
  flex: 1;
  padding: 5px 0px;
}

.role-oper {
  padding: 5px 10px 5px 0;
   30%;
  text-align: right;
  color: #7a7d88;
}

.share-pic {
  height: 60px;
}

.share-pic image {
  height: 20px;
   20px;
  margin-right: 5px;
}

.share-txt {
  height: 25px;
  line-height: 25px;
}

.role-item-name {
  background: #e4f2fb;
  padding: 5px 10px;
  color: #969ba6;
}

.admin-count {
  background: #e4f2fb;
  padding: 10px 0px;
  color: #969ba6;
  text-align: center;
}

.icon-query {
  position: relative;
  left: 90%;
  bottom: 40px;
  font-size: 26px;
  color: #aaa;
}

3、js文件

const app = getApp();
const http = require('../../../utils/http.js');
const api = require('../../../config.js');
const utils = require('../../../utils/util.js');
Page({

  /**
   * 页面的初始数据
   */
  data: {
    startX: 0, //开始坐标
    startY: 0,
    page: 1,

    admin_list: [],
    show_admin_list: [],
    default_head_pic: '../../../image/default-head-pic.png',
    keyword: '',
    role_list: [],
  },
  touchE: function(e) {
    // console.log(e);
    var that = this
    if (e.changedTouches.length == 1) {
      //手指移动结束后触摸点位置的X坐标
      var endX = e.changedTouches[0].clientX;
      //触摸开始与结束,手指移动的距离
      var disX = that.data.startX - endX;
      var delBtnWidth = that.data.delBtnWidth;
      //如果距离小于删除按钮的1/2,不显示删除按钮
      var txtStyle = disX > delBtnWidth / 2 ? "left:-" + delBtnWidth + "rpx" : "left:0rpx";

      //获取手指触摸的是哪一项
      var index = e.currentTarget.dataset.index;
      var list = that.data.show_admin_list;
      list[index].txtStyle = txtStyle;

      //更新列表的状态
      that.setData({
        show_admin_list: list
      });
    }
  },
  //手指触摸动作开始 记录起点X坐标
  touchstart: function(e) {
    //开始触摸时 重置所有删除
    this.data.show_admin_list.forEach(function(v, i) {
      if (v.isTouchMove) //只操作为true的
        v.isTouchMove = false;
    })
    this.setData({
      startX: e.changedTouches[0].clientX,
      startY: e.changedTouches[0].clientY,
      show_admin_list: this.data.show_admin_list
    })
  },
  //滑动事件处理
  touchmove: function(e) {
    var that = this,
      index = e.currentTarget.dataset.index, //当前索引
      startX = that.data.startX, //开始X坐标
      startY = that.data.startY, //开始Y坐标
      touchMoveX = e.changedTouches[0].clientX, //滑动变化坐标
      touchMoveY = e.changedTouches[0].clientY, //滑动变化坐标
      //获取滑动角度
      angle = that.angle({
        X: startX,
        Y: startY
      }, {
        X: touchMoveX,
        Y: touchMoveY
      });
    that.data.show_admin_list.forEach(function(v, i) {
      v.isTouchMove = false
      //滑动超过30度角 return
      if (Math.abs(angle) > 30) return;
      if (i == index) {
        if (touchMoveX > startX) //右滑
          v.isTouchMove = false
        else //左滑
          v.isTouchMove = true
      }
    })
    //更新数据
    that.setData({
      show_admin_list: that.data.show_admin_list
    })
  },
  /**
   * 计算滑动角度
   * @param {Object} start 起点坐标
   * @param {Object} end 终点坐标
   */
  angle: function(start, end) {
    var _X = end.X - start.X,
      _Y = end.Y - start.Y
    //返回角度 /Math.atan()返回数字的反正切值
    return 360 * Math.atan(_Y / _X) / (2 * Math.PI);
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function(options) {
    this.getRoleList();
  },

  /**
   * 获取角色列表
   */
  getRoleList: function() {
    let _this = this;
    let postData = {
      'shopid': app.globalData.shopid,
    };

    _this.setData({
      role_list: []
    });
    wx.showLoading({
      title: '角色列表获取中...',
      mask: true
    })
    http.httpGet(api.GetRoleList, postData, (res) => {
      console.log(res);
      wx.hideLoading();
      _this.getAdminList();
      if (!res) {
        return;
      }

      if (res.success) {
        let _result = res.result;
        if (_result.success) {

          this.setData({
            role_list: _result.data
          });
        } else {
          utils.showToastMessage(_result);
        }
      } else {
        utils.showToastMessage(res);
      }

    });

  },

  toAddAdmin: function(e) {
    wx.redirectTo({
      url: '../../../pages/Admin/AddAdmin/AddAdmin',
    })
  },

  saveKeyword: function(e) {
    this.setData({
      keyword: e.detail.value
    });
  },

  bindAdmin: function(e) {
    console.log(e);
    wx.navigateTo({
      url: '../../../pages/Admin/AdminQrcode/AdminQrcode?admin_no=' + e.currentTarget.dataset.adminNo + '&admin_pwd=' + e.currentTarget.dataset.adminPwd,
    })
  },

  queryAdminList: function() {
    var adminList = this.data.admin_list;
    let keyword = this.data.keyword.replace(/ /g, '');
    if (keyword) {
      var showAdminList = [];
      for (let i = 0; i < adminList.length; i++) {
        if (adminList[i].clerk_no.indexOf(keyword) > -1 || adminList[i].clerk_name.indexOf(keyword) > -1) {
          showAdminList.push(adminList[i]);
        }
      }
      for (let i = 0; i < showAdminList.length; i++) {
        showAdminList[i].id = i;
      }
      this.setData({
        show_admin_list: showAdminList
      });
    } else {
      for (let i = 0; i < adminList.length; i++) {
        adminList[i].id = i;
      }
      this.setData({
        show_admin_list: adminList
      });
    }

  },
  toAdminInfo: function(e) {
    console.log(e);
    wx.removeStorageSync('edit-admin-info');
    let adminNo = e.currentTarget.dataset.adminNo;
    if (adminNo) {
      for (let i = 0; i < this.data.admin_list.length; i++) {
        if (this.data.admin_list[i].clerk_no == adminNo) {
          wx.setStorageSync('edit-admin-info', this.data.admin_list[i])
          wx.navigateTo({
            url: '../../../pages/Admin/AdminInfo/AdminInfo?admin_no=' + adminNo,
          })
        }
      }

    } else {
      wx.showToast({
        title: '账号编号为空',
        icon: 'none '
      })
    }
  },


  getAdminList: function() {
    let _this = this;
    let postData = {
      'openid': app.globalData.openid,
      'shopid': app.globalData.shopid,
    };
    wx.showLoading({
      title: '账号获取中...',
      mask: true
    })
    _this.setData({
      admin_list: [],
      show_admin_list: []
    });
    http.httpPost(api.GetAdminList, postData, (res) => {
      console.log(res);
      wx.hideLoading();
      if (!res) {
        return;
      }

      if (res.success) {
        let _result = res.result;
        if (_result.success) {
          let _branchList = [];

          _result.data.forEach(e => {
            if (!(e.openid && e.openid == app.globalData.openid)) {
              _branchList.push(e);
            }
          });

          for (let i = 0; i < _branchList.length; i++) {
            _branchList[i].id = i;

          }



          _this.setData({
            admin_list: _branchList,
            show_admin_list: _branchList
          });
        } else {
          utils.showToastMessage(_result);
        }
      } else {
        utils.showToastMessage(res);
      }

    });
  },
  operAdmin: function(e) {
    let _this = this;
    console.log(e);
    let operType = e.currentTarget.dataset.operType;
    let adminNo = e.currentTarget.dataset.adminNo;
    let openid = e.currentTarget.dataset.openid;
    if (operType == "unbind" && !openid) {
      wx.showToast({
        title: '该账号未绑定,操作无效',
        icon: 'none'
      })
      return;
    }

    if (openid == app.globalData.openid) {
      wx.showToast({
        title: '不能操作自己绑定的账号',
        icon: 'none'
      })
      return;
    }

    wx.showModal({
      title: '提示',
      content: '确定对该账户进行' + (operType == "delete" ? "删除" : "解绑") + "操作吗?",
      confirmText: (operType == "delete" ? "删除" : "解绑"),
      confirmColor: (operType == "delete" ? "red" : "orange"),
      success: res => {
        _this.toOperAdmin(operType, adminNo);
      }
    })


  },

  toOperAdmin: function(oper_type, admin_no) {
    let _this = this;
    let postData = {
      'shopid': app.globalData.shopid,
      'openid': app.globalData.openid,
      'oper_type': oper_type,
      'admin_no': admin_no
    };

    _this.setData({
      role_list: []
    });
    wx.showLoading({
      title: oper_type == "delete" ? '删除中...' : '解绑中...',
      mask: true
    })
    http.httpPost(api.OperAdmin, postData, (res) => {
      console.log(res);
      wx.hideLoading();

      if (!res) {
        return;
      }

      if (res.success) {
        _this.onLoad();
        let _result = res.result;
        if (_result.success) {
          wx.showToast({
            title: oper_type == "delete" ? '删除成功' : '解绑成功',
          })


        } else {
          utils.showToastMessage(_result);
        }
      } else {
        utils.showToastMessage(res);
      }

    });




  },



  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function() {
    let editOper = wx.getStorageSync('edit-admin-info');
    let editOper2 = wx.getStorageSync('edit-admin-info-2');
    if (editOper || editOper2) {
      this.getAdminList();
      wx.removeStorageSync('edit-admin-info');
      wx.removeStorageSync('edit-admin-info-2')
    }
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function() {

  }
})

4、效果图

原文地址:https://www.cnblogs.com/WQ1992/p/12679405.html