「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战」。
前言
在开发小程序的时候遇到个小需求--某个页面里的某个列表,需要增加向左滑动展开修改和删除选项并且要带滑动的效果,我这想这不是简单么,小程序文档内应该有相应的组件,但是滑动组件受到限制,经过一顿操作小改了一下,效果图如下:
scroll-view组件的应用
可滚动视图区域:如果是上下滚动需要给它定义高度。
这边使用的是scroll-y左右滚动,如果是上下滚动则scroll-x。另外还有一个属性应用性比较多enable-back-to-top苹果和安卓端点顶部即可返回顶部,只支持上下滚动(可以做个参考)
<scroll-view scroll-y></scroll-view>
滚动视图渲染
渲染的列表肯定是不止一条数据,所以我这边先用循环遍历数组列表,使用block渲染多个结构块
<block wx:for="{{ list }}" wx:for-item="item" wx:for-index="index" wx:key="index">
手指触摸事件
bindtouchstart和bindtouchmove分别是手指触摸事件和手机滑动事件,通过事件监听可以进行判断,达到目的
<view class="list {{ item.isTouchMove ? 'touch-move-active' : '' }}" bindtouchstart="touchStart" bindtouchmove="touchMove" data-index="{{ index }}">
手指触摸开始
开始触摸时,操作当前触摸的模块回到滚动之前的位置,设置transform: translateX(0);,重置完成后记录手指触摸滑动的坐标 e.changedTouches[0].clientX,e.changedTouches[0].clientY
touchStart: function (e) {
let that = this;
that.data.list.forEach(function (v, i) {
if (v.isTouchMove) v.isTouchMove = false; // 只操作为true的
})
that.setData({
startX: e.changedTouches[0].clientX, // 开始X坐标
startY: e.changedTouches[0].clientY, // 开始Y坐标
warningList: that.data.warningList
})
},
手指触摸后
touchMove回调函数内event参数获取当前滑动的下标
touchMove: function (e) {
index = e.currentTarget.dataset.index,
}
获取开始x,y坐标系
var startX = that.data.startX,
var startY = that.data.startY,
滑动变化的x,y坐标系,通过changedTouches属性获取
var touchMoveX = e.changedTouches[0].clientX
var touchMoveY = e.changedTouches[0].clientY
计算滑动的角度,封装了一个方法,公式:360 * Math.atan(_Y / _X) / (2 * Math.PI);
angle: function (start, end) {
let that = this,
_X = end.X - start.X,
_Y = end.Y - start.Y;
// 返回角度 /Math.atan()返回数字的反正切值
return 360 * Math.atan(Y / X) / (2 * Math.PI);
},
获取滑动角度,分别传入X,Y轴坐标和滑动变化的X,Y坐标
angle = this.angle({
X: startX,
Y: startY
}, {
X: touchMoveX,
Y: touchMoveY
});
判断滑动角度,遍历当前列表数组,设置isTouchMove为false,表示已经滑动。
如果是滑动超过30度角,则return停止,Math.abs方法判断,如果滑动坐标超过当前坐标则为右滑动,否则为左滑。
that.data.list.forEach(function (v, i) {
v.isTouchMove = false
if (Math.abs(angle) > 30) return;
if (i == index) {
// 右滑
if (touchMoveX > startX)
v.isTouchMove = false
// 左滑
else
v.isTouchMove = true
}
})
最后更新数据
this.setData({
list: that.data.warningList
})
滑动样式
滑动内容在渲染view内和渲染内容同级展示,用display:false分到两边,两个按钮大小分别为120rpx
<view class="scrollText">
<view class="edit" bindtap="editList" data-groupid="{{item.id}}"> 修改 </view>
<view class="del" bindtap="delList" data-groupid="{{item.id}}"> 删除 </view>
</view>
列表展示数据宽度设置为100%,否则会把删除修改按钮露出来,margin-left向左偏移240rpx,这样就彻底通过滑动来控制
width: 100%;
display: flex;
padding:20rpx;
justify-content: space-between;
margin-left: -240rpx;
background-color: #fff;
flex-direction: column;
分别给展示的数据和修改删除按钮设置滑动方向,使其达到一致
-webkit-transform: translateX(0);
transform: translateX(0);
滑动动画效果和和偏移量,translateX也是为240rpx,也就是两个按钮的长度,否则不能全部把按钮展示出来。transition0.4s时长
transform: translateX(240rpx);
transition: all 0.4s;