之前在做项目的过程中有这么一个需求,列表左滑删除,这里我使用的小程序的<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); // 删除考勤组 this.setData({
list: _list.splice(idx, 1)
}) } else { } } }) },
})