「这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战」
背景
在移动端的交互中,侧滑然后展示更多的操作功能是非常常见的,这里在微信小程序侧我们也来实现一个可以侧滑展示功能的组件,有两种方式可以实现:
- 一种是纯CSS动画来实现
- 一种是利用微信小程序提供的movable-view和movable-area组件来实现。
本篇文章用css的方式来实现一般,整体思路都是一样的。
实现要点
- 防止误操作,也就是我们要计算下用户滑动的角度,是否是侧滑。这里可以用判断初始位置与最后位置的一个夹角,判断是否超过某个度数。
- 触碰其他区域,做收起操作,由于小程序的局限性,无法获取DOM导致,如果侧滑出来的操作区域收回时,一个是用户手动收回,另一个就是触发其他区域直接收回,这里就需要将对应的事件已经索引传递到外面,供外面进行逻辑判断。
- 一般侧滑都是用到数组相关的,比如删除操作,这时需要用户将对应的index传入进来。
实现
核心思路
- 核心是利用transform: translateX这个CSS的动画属性,来做区域的移位。操作区隐藏的可视范围外,当用户滑动时,将其移动出来。
- 同时只会滑出一个来,当滑动另一个时,其余的都变为收起状态。
代码实现
wxml
<view class="movable-container">
<view class="movable-view-content {{isMove ? 'touch-move-active' : ''}}" bindtouchstart="touchStart" bind:touchmove="touchMove">
<view class="view-content" style="transform: translateX({{optionsWidth}}rpx); margin-left: -{{optionsWidth}}rpx">
<slot name="content"></slot>
</view>
<view class="view-options" style="width: {{optionsWidth}}rpx; transform: translateX({{optionsWidth}}rpx)">
<slot name="options"></slot>
</view>
</view>
</view>
wxss
.movable-view-content {
display: flex;
width: 100%;
overflow: hidden;
}
.view-content {
width: 100%;
transition: all 0.3s;
}
.view-options {
transition: all 0.3s;
}
.touch-move-active .view-content,
.touch-move-active .view-options {
transform: translateX(0) !important;
}
使用该组件 在页面中引入该组件,然后对应的wxml
<block wx:for="{{slideList}}">
<slideContainer optionsWidth="{{200}}" bind:touchStart="handleTouchStart" isTouchMove="{{item.isTouchMove}}" bind:optionShow="handleOptionShow" index="{{index}}">
<view slot="content" class="content"></view>
<view slot="options" class="options"></view>
</slideContainer>
</block>
}
.content {
height: 80rpx;
width: 100vw;
background-color: aliceblue;
border-bottom: 1rpx solid #ccc;
}
.options {
height: 80rpx;
width: 200rpx;
background-color: red;
}
js逻辑
Page({
data: {
slideList: [{value: 1}, {value:2}, {value: 3}, {value: 4}]
},
handleOptionShow(e) {
const {slideList} = this.data;
slideList.forEach((item, index) => {
if (e.detail === index) {
item.isTouchMove = true;
}
})
this.setData({
slideList: slideList.slice(0)
})
},
handleTouchStart(e) {
const {slideList} = this.data;
// 防止用户多触点触发,也就是多手指
if(e.detail.touches.length > 1) {
return;
}
slideList.forEach((item, index) => {
if (e.detail.index !== index) {
item.isTouchMove = false;
}
})
this.setData({
slideList: slideList.slice(0)
})
},
})
注意点: 这里我们是在使用的组件,对滑块做处理,在用户触碰滑块以及操作区展示出来时,分别发送对应的事件,将当前的index传入。 每一项都记录一个状态,是否处于展示操作区,用来处理当用户滑动其他项时,将其收起。
总结
其实实现一个侧滑组件还是很简单的,但难点是如何保证我们的体验,这里总结了3点:
- 一个是误操作问题,注意用户滑动方向,防止将用户非滑动操作,引起滑块的滑动
- 而是防止用户的多手势操作,这里只判断一个触点的情况,对于多触点不进行任何触发
- 同时只存在一项滑动中的状态,其他项都是收起状态。