上拉加载和下拉刷新是平常中常遇到的场景,当然也有很多框架之类的,不过之前我遇到过一种下拉刷新+滑动tab的一种需求,就是有许多tab页面,可以左右滑动,并且每个页面都可以上拉加载。这种组合其实就是上拉刷新+swiper,虽然我们可以用两个框架拼凑成我们想要的效果,但是比较麻烦,而且效果也不太好。

我之前在mui库中发现他们做了这两种场景的组合。这两种情况组合在一起之所以复杂,是因为存在一种手势锁定的情况。就是你上下滑的时候,左右不能动;左右滑的时候,上下不能动。下面先看看做好的demo:

上面的demo看是简单,实则包含了很多内容,上拉加载,下拉刷新,swiper,以及两者的联动,现在我们就来逐个分析。

上拉刷新

上拉刷新是整个部分中最简单的了,实现原理主要是监听scroll事件,然后判断当前是否滚动到页面底部了,同时可以设置一个distance,表示距离底部多少的时候,触发下拉加载,关键代码:

下拉刷新

下拉刷新的主要思路是在列表页的上面增加一个div,然后当用户下拉的时候,通过判断移动的距离,设置div的高度,这样看起来就是在下拉。

background Layer 1 这是内容列表 div,控制其高度

代码实现上,主要有两个问题,第一是如何判断用户正在下拉,而不是上拉?第二是在什么时候触发控制div的高度。

对于第一个问题,我们这里需要对touchstart,touchmove,touchend/mousedown,mousemove,mouseup做一个处理,记录包括方向,角度等信息,关键代码如下:

上面监听window的开始/移动/离开事件,然后记录一些信息,识别出方向,角度等信息,最后触发自定的dragStart,dargMove,dragEnd事件。这里大家可能会比较费解,为啥要搞个这么复杂的东西出来呢?

这要主要是将手势操作和业务逻辑代码分离开,好管理;而且一套代码可以公用,因为这里需要手势识别的很多,起码有3套是需要它的;最关键这里是在window上监听的,相比对于某一个具体元素的监听,移动监听区域更广。

对于之前讲到的第二个问题,就是我们在dragMove的时候判断此时的scrollTop是否<=0,并且此时是向下拉的,关键代码如下:

上面代码中有一个最大移动距离,如果超过它,移动就开始变的缓慢;还有一个对角度的识别,如果角度小于45度,也就是趋向左右滑动,我们取消,不参与计算。

多页面+上拉加载

这种情况比单独的上拉+下拉复杂的多,我们先来看看页面结构:

background Layer 1 北京 上海 广州 左滑翻页 右滑翻页 左滑 右滑 下拉刷新 上拉加载

我们可以看到,内容页面需要同时支持四个方向的手势操作,因此我们需要做一个手势锁。什么意思呢?假如你斜20度(和水平方向的角度)右上滑动,那么就识别为右滑动,锁定此时只能左右滑动,不能上下滑动;你斜80度(和水平方向角度)右下滑动,那么识别为向下,锁定上下方向,水平方向不能动。

上面讲的内容传递了两个信息:1.如果识别现在是往上下左右哪个方向移动,2.如何锁定某个方向。

判断方向这里比较简单,就是直接看水平位移和垂直位移的差,如果水平位移多,那么就是水平方向;如果垂直唯一多,那么就是竖直方向。不过这里比较有意思的是它并不是计算两个连续点之间的位移关系,而是间隔一段时间的,例如本例中就是间隔25ms计算的方向。

锁定方向就是将我们第一计算得到的哪个方向存起来,然后在移动的时候判断,只处理符合当前方向的事件。例如对于上拉,下拉来说,它们只关心垂直方向;而对于滑动来说,它们只关心水平方向。

上面代码分别来之侧滑,上下拉的核心手势锁代码。定时去计算手势方向的代码在之前的手势代码也已经有了。

手势代码中有一个比较有意思的东西,就是计算touch的中心位置。

我之前一直以为这个没什么用,但是在侧滑的时候,我发现其实可以多指侧滑,如果按照我之前的算法,只计算touch[0]的位置,那么当第二个手指开始滑动的时候,就没有任何反应。但是如果有了这个计算多指中心的方法,那么可以解决多指侧滑的问题。

DEMO下载

点击下载 [0积分]一共下载0

其他文章

0
我要评论

评论

返回
×

我要评论

回复:

昵称:(昵称不超过20个字)

图片:

提交
还可以输入500个字