前言:
现在很多程序上都有左滑删除的效果,其实实现很简单,今天我们主要来记录一下小程序的左滑删除的实现过程。
效果图:
实现效果:
- 当我们在该条记录上进行左滑操作时,整条记录跟着向左移动,同时右侧的删除按钮会显示出来。
- 当我们点击删除按钮时,就会把该条记录删除掉。
- 如果不想删除该记录,可以右滑取消,或者随意点击一个位置都可以使右侧的删除按钮隐藏回到原样。
设计思路:
- 首先在页面上每条 item 记录分为上下两层,上面的
view
包裹正常展示的内容,下面的view
存放左滑的显示的内容; - 元素移动使用的是
transform
属性; - 这里用到的微信小程序的 api 是
touch
的相关事件:touchstart
和touchmove
来实现view
视图跟随手指移动。 微信小程序 - 事件 - 在
touchstart
时,通过clientX, clientY
或者pageX, pageY
来监听记录触摸开始时的(x, y)的位置;在touchMove
中持续监听触摸点(x, y)的位置,并且记录下来。之后再对开始的触摸位置和结束的触摸位置进行逻辑的判断,如果移动距离大于开始的距离,那么就是右滑,将data数据中的isTouchMove
置为false
不进行展示;如果移动距离小于开始的位置,那么就是左滑,将isTouchMove
置为true
,页面中的按钮就会展示出来,可以进行删除等其他操作。
上面就是实现的思路,废话不多说,直接上代码了。
代码实现:
wxml 代码:
// touch.wxml
<view class="records_row" wx:for="{{records}}" wx:key="index">
<view class="records_row_content {{item.isTouchMove ? 'touch_move' : ''}}" data-index="{{index}}"
bindtouchstart="touchStart" bindtouchmove="touchMove">
<view class="records_row_left"></view>
<view class="records_content">
<view class="records_bs">
{{item.identification}}
</view>
<view class="records_time">
{{item.time}}
</view>
</view>
<view class="records_del" catchtap="del" data-index="{{index}}">删除</view>
</view>
</view>
wxss 代码:
.records_row {
width: 710rpx;
height: 152rpx;
background: #FFFFFF;
box-shadow: 0px 0px 16rpx 0px #EAEAEA;
border-radius: 12rpx;
margin-top: 24rpx;
margin-left: 20rpx;
display: flex;
justify-content: space-between;
align-items: center;
overflow: hidden;
}
.records_row_left {
width: 8rpx;
height: 152rpx;
background: #5AC8FF;
border-radius: 12rpx 0px 0px 12rpx;
margin-right: 30rpx;
}
.records_row_content {
height: 152rpx;
display: flex;
flex: 1;
font-size: 28rpx;
font-weight: 400;
color: #333333;
padding-right: 58rpx;
}
.records_bs {
max-width: 604rpx;
max-height: 80rpx;
display: block;
text-overflow: ellipsis;
word-wrap: break-word;
font-size: 28rpx;
font-weight: 400;
color: #333333;
line-height: 40rpx;
overflow: hidden;
}
.records_time {
font-size: 24rpx;
font-weight: 400;
color: #999999;
line-height: 34rpx;
margin-top: 8rpx;
}
.records_content {
width: 600rpx;
display: flex;
flex-direction: column;
justify-content: center;
}
.touch_move .records_content,
.touch_move .records_row_left,
.touch_move .records_del {
transform: translateX(-100rpx);
}
.touch_move .records_del {
transform: translateX(-80rpx);
}
.records_del {
background-color: #FD7373;
width: 150rpx;
height: 150rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: #fff;
transform: translateX(80rpx);
transition: all 0.4s;
}
/* 如果担心transform的兼容问题,可以再加上 -webkit 前缀,-webkit-transform */
js 代码:(解释的比较清楚,大家可以看看注释)
// pages/touch/touch.js
Page({
/**
* 页面的初始数据
*/
data: {
records: [{
identification: '左滑删除1',
time: '2020-11-04 11:02:43',
isTouchMove: false //默认隐藏删除
}, {
identification: '左滑删除2',
time: '2020-11-04 11:02:43',
isTouchMove: false //默认隐藏删除
}, {
identification: '左滑删除3',
time: '2020-11-04 11:02:43',
isTouchMove: false //默认隐藏删除
}],
startX: 0, // 开始X坐标
startY: 0, // 开始Y坐标
},
// 手指触摸开始事件,记录开始的(X,Y)位置
touchStart: function (e) {
// 开始触摸时,将 isTouchMove 为 true 的置为 false,开始新的操作
this.data.records.forEach(function (item, index) {
if (item.isTouchMove)
item.isTouchMove = false;
})
// 更新数据,记录开始的位置
this.setData({
startX: e.changedTouches[0].clientX,
startY: e.changedTouches[0].clientY,
records: this.data.records
})
},
// 手指滑动事件
touchMove: function (e) {
// 定义变量进行数据存储
let that = this
let currentIndex = e.currentTarget.dataset.index //当前索引
let startX = that.data.startX // 开始X坐标
let startY = that.data.startY // 开始Y坐标
let touchMoveX = e.changedTouches[0].clientX // 滑动变化X坐标
let touchMoveY = e.changedTouches[0].clientY // 滑动变化Y坐标
that.data.records.forEach((item, index) => {
item.isTouchMove = false
// 判断当前点击的是哪一个,进行操作
if (index == currentIndex) {
if (touchMoveX > startX) // 滑动位置大于开始位置 => 右滑
item.isTouchMove = false
else // => 左滑
item.isTouchMove = true
}
})
//更新数据
that.setData({
records: that.data.records
})
},
// 删除事件
del: function (e) {
this.data.records.splice(e.currentTarget.dataset.index, 1)
this.setData({
records: this.data.records
})
}
})
20201207 更新
今天在看WeUI组件库时,发现新增了几个新的组件(也可能是之前就有,我没有发现),看到在表单组件中有一个 Slideview 组件,是一个左滑删除组件,跟我这个实现功能效果是一样的,所以就拿到这里跟大家一起分析一下。
至于如何使用WeUI组件库组件,不知道的小伙伴请移步至 微信小程序之WeUI组件库的使用 查看。
官方效果:
请看代码:
- 首先需要先引入相关的组件
// 在 page.json 中引入该组件
{
"usingComponents": {
"mp-slideview": "weui-miniprogram/slideview/slideview"
}
}
// 组件内部实现需要引入的组件
{
"usingComponents": {
"mp-cells": "../components/cells/cells",
"mp-cell": "../components/cell/cell",
"mp-slideview": "../components/slideview/slideview"
}
}
- page.wxml
<view class="page">
<view class="page__hd">
<view class="page__title">Slideview</view>
<view class="page__desc">左滑操作</view>
</view>
<view class="page__bd">
<view class="weui-cells">
<mp-slideview buttons="{{slideButtons}}" bindbuttontap="slideButtonTap">
<mp-cell value="左滑可以删除" footer="说明文字"></mp-cell>
</mp-slideview>
</view>
<view class="weui-slidecells">
<mp-slideview buttons="{{slideButtons}}" icon="{{true}}" bindbuttontap="slideButtonTap">
<view class="weui-slidecell">
左滑可以删除(图标Button)
</view>
</mp-slideview>
</view>
</view>
</view>
- page.js
var base64 = require("../images/base64");
Page({
onLoad: function(){
this.setData({
icon: base64.icon20,
slideButtons: [{
text: '普通',
src: '/page/weui/cell/icon_love.svg', // icon的路径
},{
text: '普通',
extClass: 'test',
src: '/page/weui/cell/icon_star.svg', // icon的路径
},{
type: 'warn',
text: '警示',
extClass: 'test',
src: '/page/weui/cell/icon_del.svg', // icon的路径
}],
});
},
slideButtonTap(e) {
console.log('slide button tap', e.detail)
}
});
以上代码来自官方组件库,有什么问题欢迎大家讨论学习。
就此,小程序的手动左滑删除效果基本实现,还可以在此基础上进行更多的扩展,把它变成一个更加强大的功能。
欢迎大家评论点赞,如果有任何问题欢迎留言讨论,共同进步。