左滑删除效果在app的交互方式中十分流行,比如全民应用微信
再比如曾引起很大反响的效率app Clear
从技术上来说,实现这个效果并不困难,响应一下滑动操作,移动一下组件,再加上些坐标计算,状态记录就可以了。也有一些文章介绍了在小程序上如何实现这一效果,不过我基本可以确定这些开发者没有在真机上详细测试,因为经我实践发现,在小程序上想要完美实现这个效果几乎是不可能完成的任务。
这一切要从小程序的事件机制说起。对于滑动类操作,小程序提供了bind
和catch
两种响应事件的方式,区别在于是否阻止事件冒泡,但却没有提供preventDefault
方法,也就是说无法在程序中动态确定是否阻止某个事件冒泡。
然后再说一下小程序的另一个特性,这个特性只在真机上有效,那就是框架默认为page提供了垂直方向的滚动效果,无需写一行代码,并且小程序还贴心的提供了onPullDownRefresh
和onReachBottom
,嗯,一切都很完美。
然后当这些特性遇到左滑效果,那就尴尬了。完美的左滑删除效果,当判定为水平滑动时,要忽略用户垂直方向上的移动(毕竟不能指望用户的手指不会上下抖动吧)。然而因为没有preventDefault
方法,要么catch住滑动事件,要么你就只能期待用户的手指严格水平滑动了。
由于上述原因,在我见到的小程序中,几乎没有使用左滑删除操作的,说几乎是因为确实有一款实现了该效果,印象微笔记清单
可以看到在左滑时页面也会同时上下滚动,体验并不好。(顺便说一句,印象微笔记清单早起版本使用scroll-view
实现该效果,体验就更差了)
当然,也可以catch滑动事件,不过这样水平滑动时没问题,垂直滑动时你也不会看到任何反应了。
当我发现这些问题时感到十分沮丧,不过我想问题的核心就是要能动态阻止页面垂直滚动。而除了view之外,scroll-view也具备垂直滚动的能力,并且还有一个属性scroll-y Boolean false 允许纵向滚动
。是的,我想你们也想到了,只要在合适的条件下动态设置该属性,那就应该可以实现想要的效果了。
从实现上来讲,应该首先禁用垂直滚动,在判定用户为垂直操作后激活该属性,嗯,完美。但事实又一次打了我的脸,在touchmove
事件中激活该属性并不能激活垂直滚动效果。
那就反过来,首先激活垂直滚动,在判定水平操作后禁用该属性。嗯,实践证明该方法可行,但仍然有问题。在我们判定滑动方向之前,用户很有可能在垂直方向有移动,虽然很微小,但依然会感受到页面的上下滚动。
下面是我按照该思路实现的仿微信首页效果
在后续的文章中,我会展示另一种实现该效果的方法,可以完美消除页面垂直滚动问题,不过仍然会有其它限制。
最后是源码地址, 感兴趣的同学可以下载体验。