之前在做項目的過程中有這么一個需求,列表左滑刪除,這里我使用的小程序的<movable-area/>(官方地址)實現的,最終研究了一番,實現了產品需求。效果圖如下:
實現思路:
1、最外層標簽使用movable-area標簽,寬高必須固定;
2、子標簽必須使用movable-view,寬高和父元素movable-area一樣,不是子標簽無法移動;
3、使用view標簽將,列表內容和刪除按鈕包裹起來;
4、列表內容和刪除按鈕使用css屬性transform: translateX(108rpx)設置,達到隱藏刪除按鈕的目的;再給列表內容添加屬性margin-left: -180px,使其正常顯示;
5、使用movable-area標簽實現左滑刪除,適用於高度固定的列表;
6、若出現蘋果真機頁面還能整體左滑的問題,可在最外層標簽添加css屬性overflow-x: hidden,就可以解決頁面整體滑動的問題了;
代碼部分:
<!-- pages/index/index.wxml --> <view class="container"> <view class="mess padding">考勤規則相同的人設置到同一考勤組,以便於統計</view> <!-- 考勤組列表 --> <block wx:for="{{list}}" wx:key="index"> <movable-area class='movable-area'> <movable-view direction="horizontal" class='movable-view bg_white'> <view class="touch-item {{item.isTouchMove ? 'touch-move-active' : ''}}" data-index="{{index}}" bindtouchstart="touchstart" bindtouchmove="touchmove"> <view class="content" bindtap='toDetail' data-id="{{item.groupId}}"> <view class="attendance_name font_size">{{item.groupName}}</view> <view class="attendance_text flex-x"> <view class="attendance_text_l font_size">成員:</view> <view class="attendance_text_r font_size">{{item.numberOfPeople}}人</view> </view> <view class="attendance_text flex-x"> <view class="attendance_text_l font_size">負責人:</view> <view class="attendance_text_r font_size">{{item.principalName}}</view> </view> <view class="attendance_text flex-x"> <view class="attendance_text_l font_size">固定班制:</view> <view class="attendance_text_r font_size">{{item.attDateList[0]}}至{{item.attDateList[(item.attDateList.length-1)]}} {{item.sTime}}-{{item.eTime}}</view> </view> </view> <view class="del bg_red font_size" catchtap="del" data-idx="{{index}}">刪除</view> </view> </movable-view> </movable-area> </block> <view class="btn font_size padding" bindtap="addAttendance">+新增考勤組</view> </view>
/* pages/index/index.wxss */ page { background: #f2f2f2; } .font_size { font-size: 28rpx; } .mess { font-size: 26rpx; } .mess { color: #999; line-height: 60rpx; padding: 0 30rpx; box-sizing: border-box; } .btn { width: 90%; height: 90rpx; background: #fff; color: #999; text-align: center; margin: 0 auto; line-height: 90rpx; } /* 列表布局 */ .movable-area { width: 100%; height: 200rpx; margin-bottom: 20rpx; } .movable-view { width: 100%; height: 100%; } .touch-item { display: flex; justify-content: space-between; width: 100%; height: 100%; overflow: hidden; } .content { width: 100%; margin-right: 0; padding: 10rpx 10rpx 20rpx 30rpx; box-sizing: border-box; -webkit-transition: all 0.4s; transition: all 0.4s; -webkit-transform: translateX(180rpx); transform: translateX(180rpx); margin-left: -180rpx; overflow: hidden; } .del { width: 180rpx; display: flex; flex-direction: column; align-items: center; justify-content: center; color: #fff; -webkit-transform: translateX(180rpx); transform: translateX(180rpx); -webkit-transition: all 0.4s; transition: all 0.4s; } .touch-move-active .content, .touch-move-active .del { -webkit-transform: translateX(0); transform: translateX(0); } .attendance_name { color: #999; margin-bottom: 8rpx; } .attendance_text > view { margin-bottom: 8rpx; color: #828282; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; } .attendance_text_l { width: 17%; flex-shrink: 0; } .attendance_text_r { flex-grow: 1; }
// pages/index/index.js Page({ /** * 頁面的初始數據 */ data: { list: [ { groupId: 1, //考勤組ID groupName: '正常班', principalName: '路老師', //考勤負責人姓名 numberOfPeople: '1', //考勤組人數 attDate: '周一至周五 8:00-17:00', //固定班制 isTouchMove: false, //默認全隱藏刪除 }, { groupId: 2, //考勤組ID groupName: '實習生考勤', principalName: '路老師', //考勤負責人姓名 numberOfPeople: '1', //考勤組人數 attDate: '周一至周五 7:20-17:20', //固定班制 isTouchMove: false, //默認全隱藏刪除 }, ], //考勤組列表 startX: 0, //開始x坐標 startY: 0, //開始y坐標 }, /** * 生命周期函數--監聽頁面加載 */ onLoad: function(options) { }, /** * 手指觸摸動作開始 記錄起點X坐標 */ touchstart: function(e) { // console.log('進來了', e) //開始觸摸時 重置所有刪除 this.data.list.forEach(function(v, i) { if (v.isTouchMove) { //只操作為true的 v.isTouchMove = false; } }) this.setData({ startX: e.changedTouches[0].clientX, startY: e.changedTouches[0].clientY, list: this.data.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, //滑動變化X坐標 touchMoveY = e.changedTouches[0].clientY, //滑動變化Y坐標 //獲取滑動角度 angle = that.angle({ X: startX, Y: startY }, { X: touchMoveX, Y: touchMoveY }); that.data.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({ list: that.data.list }) }, /** * 計算滑動角度 * start 起點坐標 * end 終點坐標
*Math.PI
表示一個圓的周長與直徑的比例,約為 3.14159;PI就是圓周率π,PI是弧度制的π,也就是180°
*/ angle: function(start, end) { var _X = end.X - start.X, _Y = end.Y - start.Y return 360 * Math.atan(_Y / _X) / (2 * Math.PI); }, /** * 刪除 */ del(e) { var id = e.currentTarget.dataset.idx,
_list = this.data.list; wx.showModal({ title: '提示', content: '確定刪除該考勤組嗎?', confirmColor: "#f16765", success: res => { if (res.confirm) { isShow = false; this.touchstart(e);
_list.splice(idx, 1); // 刪除考勤組 this.setData({
list: _list
}) } else { } } }) },
})