上一个小程序的项目里面做过这个功能,当时没有记录下来,今天特意做了一个小的demo放在了github上面,下次在开发中遇到的话就可以直接拿下来代码复用了。效果很简单,类似于微信扣扣删除聊天栏的效果,想左滑动,出现删除按钮,点击即可删除。
wxml:
<!--index.wxml--> <view class="container"> <scroll-view style='height:{{height}}px;' scroll-y='{{scrollY}}' class='msg-list' bindscroll='onScroll'> <view wx:for="{{msgList}}" wx:key="id" class='msg-item' animation='{{item.wrapAnimation}}'> <view id='{{item.id}}' class='msg' animation='{{item.animation}}' bindtouchstart='ontouchstart' bindtouchmove='ontouchmove' bindtouchend='ontouchend'> <image class='header-img' src="{{item.headerImg}}"></image> <text class='user-name'>{{item.carid}}</text> <text class='msg-text'>{{item.msgText}}</text> <image class='site-img' src="{{item.siteImg}}"></image> </view> <view class='msg-menu'> <view id='{{item.id}}' class='menu-delete' bindtap='onDeleteMsgTap' bindlongtap='onDeleteMsgLongtap'> 删除 </view> <view id='{{item.id}}' class='menu-mark' bindtap='onMarkMsgTap' bindlongtap='onMarkMsgLongtap'> 试驾 </view> </view> </view> </scroll-view> </view>
wxss:
/**index.wxss**/ ::-webkit-scrollbar { width: 0; height: 0; color: transparent; } .msg-item { width: 100%; height: 150rpx; border-bottom: 1rpx solid rgb(233, 233, 233); position: relative; left: 0; top: 0; overflow: hidden; } .msg { position: absolute; width: 100%; height: 150rpx; left: 0; top: 0; z-index: 100; background-color: #fff; } .header-img { position: absolute; width: 100rpx; height: 100rpx; left: 30rpx; top: 40rpx; border-radius: 10%; } .site-img { position: absolute; width: 70rpx; height: 70rpx; right: 30rpx; top: 40rpx; border-radius: 10%; } .user-name { position: absolute; left: 150rpx; top: 33rpx; font-weight: 600; font-size: 35rpx; } .msg-text { position: absolute; left: 150rpx; bottom: 30rpx; font-size: 80%; color: rgb(127, 127, 127); } .msg-menu { position: absolute; width: 100%; height: 150rpx; left: 0; top: 0; z-index: 0; } .menu-delete { position: absolute; width: 150rpx; height: 148rpx; top: 1rpx; right: 0; background-color: rgb(255, 58, 50); color: #fff; text-align: center; line-height: 150rpx; } .menu-mark { position: absolute; width: 200rpx; height: 148rpx; top: 1rpx; right: 150rpx; background-color: rgb(200, 199, 205); color: #fff; text-align: center; line-height: 150rpx; } /* 底部按钮 */ .Scancode { font-size: 39rpx; background: rgb(82, 80, 80); position: fixed; bottom: 0; display: flex; width: 100%; justify-content: center; color: #fff; border-radius: 0px; } .search { width: 80rpx; height: 80rpx; line-height: 80rpx; background: #fff; border: 1px solid #c8c8c8; position: fixed; bottom: 130rpx; left: 16rpx; display: flex; justify-content: center; border-radius: 50rpx; /* -webkit-box-shadow:3px 3px 3px #c8c8c8 ; -moz-box-shadow:3px 3px 3px #c8c8c8 ; box-shadow:3px 3px 3px #c8c8c8 ; */ } .search .img { width: 40rpx; height: 40rpx; margin-top: 10rpx; } .user { width: 80rpx; height: 80rpx; line-height: 80rpx; border: 1px solid #c8c8c8; background: #fff; position: fixed; bottom: 130rpx; right: 16rpx; display: flex; color: #fff; justify-content: center; border-radius: 50rpx; /* -webkit-box-shadow:3px 3px 3px #c8c8c8 ; -moz-box-shadow:3px 3px 3px #c8c8c8 ; box-shadow:3px 3px 3px #c8c8c8 ; */ } .user .img { width: 40rpx; height: 40rpx; margin-top: 10rpx; }
js
//index.js //获取应用实例 var app = getApp() Page({ data: { msgList:[], height:0, scrollY:true }, swipeCheckX:35, //激活检测滑动的阈值 swipeCheckState:0, //0未激活 1激活 maxMoveLeft:185, //消息列表项最大左滑距离 correctMoveLeft:175, //显示菜单时的左滑距离 thresholdMoveLeft: 75,//左滑阈值,超过则显示菜单 lastShowMsgId:'', //记录上次显示菜单的消息id moveX:0, //记录平移距离 showState:0, //0 未显示菜单 1显示菜单 touchStartState:0, // 开始触摸时的状态 0 未显示菜单 1 显示菜单 swipeDirection:0, //是否触发水平滑动 0:未触发 1:触发水平滑动 2:触发垂直滑动 onLoad: function() { this.pixelRatio = app.data.deviceInfo.pixelRatio; var windowHeight = app.data.deviceInfo.windowHeight; var height = windowHeight; for (var i = 0; i < 5; i++) { var msg = {}; msg.carid = '' + '沪D086' + i+1; msg.msgText = '10801:10001' msg.id = 'id-' + i+1; msg.headerImg = '../../img/car.png'; msg.siteImg = '../../img/site.png'; this.data.msgList.push(msg); } this.setData({msgList:this.data.msgList, height:height}); }, ontouchstart: function(e) { if (this.showState === 1) { this.touchStartState = 1; this.showState = 0; this.moveX = 0; this.translateXMsgItem(this.lastShowMsgId, 0, 200); this.lastShowMsgId = ""; return; } this.firstTouchX = e.touches[0].clientX; this.firstTouchY = e.touches[0].clientY; if (this.firstTouchX > this.swipeCheckX) { this.swipeCheckState = 1; } this.lastMoveTime = e.timeStamp; }, ontouchmove: function(e) { if (this.swipeCheckState === 0) { return; } //当开始触摸时有菜单显示时,不处理滑动操作 if (this.touchStartState === 1) { return; } var moveX = e.touches[0].clientX - this.firstTouchX; var moveY = e.touches[0].clientY - this.firstTouchY; //已触发垂直滑动,由scroll-view处理滑动操作 if (this.swipeDirection === 2) { return; } //未触发滑动方向 if (this.swipeDirection === 0) { console.log(Math.abs(moveY)); //触发垂直操作 if (Math.abs(moveY) > 4) { this.swipeDirection = 2; return; } //触发水平操作 if (Math.abs(moveX) > 4) { this.swipeDirection = 1; this.setData({scrollY:false}); } else { return; } } //禁用垂直滚动 // if (this.data.scrollY) { // this.setData({scrollY:false}); // } this.lastMoveTime = e.timeStamp; //处理边界情况 if (moveX > 0) { moveX = 0; } //检测最大左滑距离 if (moveX < -this.maxMoveLeft) { moveX = -this.maxMoveLeft; } this.moveX = moveX; this.translateXMsgItem(e.currentTarget.id, moveX, 0); }, ontouchend: function(e) { this.swipeCheckState = 0; var swipeDirection = this.swipeDirection; this.swipeDirection = 0; if (this.touchStartState === 1) { this.touchStartState = 0; this.setData({scrollY:true}); return; } //垂直滚动,忽略 if (swipeDirection !== 1) { return; } if (this.moveX === 0) { this.showState = 0; //不显示菜单状态下,激活垂直滚动 this.setData({scrollY:true}); return; } if (this.moveX === this.correctMoveLeft) { this.showState = 1; this.lastShowMsgId = e.currentTarget.id; return; } if (this.moveX < -this.thresholdMoveLeft) { this.moveX = -this.correctMoveLeft; this.showState = 1; this.lastShowMsgId = e.currentTarget.id; } else { this.moveX = 0; this.showState = 0; //不显示菜单,激活垂直滚动 this.setData({scrollY:true}); } this.translateXMsgItem(e.currentTarget.id, this.moveX, 500); //this.translateXMsgItem(e.currentTarget.id, 0, 0); }, onDeleteMsgTap: function(e) { this.deleteMsgItem(e); }, onDeleteMsgLongtap: function(e) { console.log(e); }, onMarkMsgTap: function(e) { console.log(e); }, onMarkMsgLongtap: function(e) { console.log(e); }, getItemIndex: function(id) { var msgList = this.data.msgList; for (var i = 0; i < msgList.length; i++) { if (msgList[i].id === id) { return i; } } return -1; }, deleteMsgItem: function(e) { var animation = wx.createAnimation({duration:200}); animation.height(0).opacity(0).step(); this.animationMsgWrapItem(e.currentTarget.id, animation); var s = this; setTimeout(function() { var index = s.getItemIndex(e.currentTarget.id); s.data.msgList.splice(index, 1); s.setData({msgList: s.data.msgList}); }, 200); this.showState = 0; this.setData({scrollY:true}); }, translateXMsgItem: function(id, x, duration) { var animation = wx.createAnimation({duration:duration}); animation.translateX(x).step(); this.animationMsgItem(id, animation); }, animationMsgItem: function(id, animation) { var index = this.getItemIndex(id); var param = {}; var indexString = 'msgList[' + index + '].animation'; param[indexString] = animation.export(); this.setData(param); }, animationMsgWrapItem: function(id, animation) { var index = this.getItemIndex(id); var param = {}; var indexString = 'msgList[' + index + '].wrapAnimation'; param[indexString] = animation.export(); this.setData(param); }, })