-
Notifications
You must be signed in to change notification settings - Fork 0
Description
左滑删除是目前很多应用都必不可少的功能,像QQ,微信都有使用这种方式,并且在此基础上有拓展的交互设计。
需求在哪?
我们青柚工作室的一个正在开发的小程序项目中,UI哥哥设计了一个左滑的组件,想让用户通过左滑来取消对这个Item的关注。
怎么去做 ?
我一开始觉得在小程序中不存在 dom 结构不是很方便完成这个效果,后来在京东商城小程序中发现了这个类似的实现,于是开始思考如何去完成这个看似很简单的需求。
通过观察发现其实就是最普通的touchstart touchend事件就行了,于是我几分钟就写出了下面这段代码:
touchStart(e) {
this.touchStartClientX = e.touches[0] ? e.touches[0].clientX : 0
},
touchEnd(e) {
this.touchEndClientX = e.touches[0] ? e.touches[0].clientX : 0
const offsetX = Number(this.touchStartClientX) - Number(this.touchEndClientX)
if (offsetX > 30) {
this.$_slideFlex = this.slideFlex
} else if (-offsetX > 30) {
this.$_slideFlex = 0
}
}在没打开控制台前,嗯,很美好,效果实现了,可以收拾东西回家了。
但是当我打开控制之后,"Oh! WTF! What's this ?"
报错是什么?
当我手指离开的那一刹那,可控制台红红的字告诉我 e.touches[0] is undefined,怎么会呢,按照我的认知,在发生触摸的时候会产生一个touch对象,触摸事件中的touches数组用来记录当前触摸操作产生的touch对象,注意: 一个触摸点只会产生一个touch对象,所以就算是touchmove事件发生,每一次move都会新建一个触摸点,从而touches的数组长度依然为1。
原因
问题来了,既然touches的长度为1,那么为什么我touchend的时候会报错呢,经过一番查询,找了原因:touchend事件发生的时候意味着触摸事件结束,事件触发的时刻,touch对象已经被销毁掉了,所以touches数组的长度为0。
解决方案
在touchend事件中获取触摸点位置的属性不使用touches[0],而使用changedTouches[0]来获取,这个属性是用来记录上次触摸改变的touch对象,所以这个值就是用户在结束触摸操作之前产生的最后一个触摸对象,通过它就可以获取到坐标。
结论
与touchend事件中touches[0]是undefined类似的是,touchstart事件中changedTouches[0]也是undefined,因为触摸开始的瞬间是不存在上一个触摸点的。
关键 以上的结论完全是基于单指触摸的,如果是多指触摸就存在不成立的情况,就需要借助手势操作的事件一起来分析用户行为了。
最后的代码:
touchStart(e) {
this.touchStartClientX = e.touches[0] ? e.touches[0].clientX : 0
},
touchEnd(e) {
this.touchEndClientX = e.changedTouches[0] ? e.changedTouches[0].clientX : 0
const offsetX = Number(this.touchStartClientX) - Number(this.touchEndClientX)
if (offsetX > 30) {
this.$_slideFlex = this.slideFlex
} else if (-offsetX > 30) {
this.$_slideFlex = 0
}
}最后的最后推一下我写的 wepy-slide-card,还在不断改进中,但是这个组件的目的只是为了滑块的交互,不会将其演变成比较重的swiper组件,使用方法:
npm install wepy-slide-card --saveorz。。卒。。