微信小程序向左滑动删除操作(类仿微信、QQ)
2018-12-07 本文已影响135人
祈澈菇凉
上一个小程序的项目里面做过这个功能,当时没有记录下来,今天特意做了一个小的demo放在了github上面,下次在开发中遇到的话就可以直接拿下来代码复用了。效果很简单,类似于微信扣扣删除聊天栏的效果,想左滑动,出现删除按钮,点击即可删除。
github地址:https://github.com/wangxiaoting666/swipeleft-delete
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);
},
})
原文作者:祈澈姑娘。 技术博客:https://www.jianshu.com/u/05f416aefbe1
90后前端妹子一枚,爱编程,爱运营,爱折腾。长期坚持总结工作中遇到的技术问题。