看一个简单的小程序拖拽排序:

小程序拖拽排序 gif 小程序拖拽排序

思路分析

首先视图层我们用的是view,因为这个没有兼容问题。看网上拖动排序的demo,大多是绑定movestart,move,moveend事件,维护一个x,y,current变量,通过current在视图层中的wx:for找到当前正在移动的元素,将后利用current==item.id,给它一个moving的class,其中这个moving的class是absolute定位,给所有元素设置left和top,但是只有absolute才会起作用。网上的这种方式可以实现,只不过有一些问题,就是一旦一个元素变成absolute定位,那么之前的位置就会产生空缺,被后面的元素给挤上去。

我们这里为了避免上述方案的问题,从一开始就采用absolute布局,然后利用屏幕的宽度,计算出所有元素的位置,通过left,top纪录当前元素的位置,同时保存_left,_top,因为当一个元素移动的时候left,top改变,当它遇到另外一个元素的时候,通过交换_left,_top信息,可以到那个元素的位置。

首先我们要根据屏幕的宽度来确定每个view的位置,绘制过程大致如下:

background Layer 1 水平间隙s_h 模块宽度u_w 垂直间隙s_v 模块高度u_h

关键绘制代码如下:

绘制完之后就会movestart,move,moveend事件处理了,这里我们拿moveend看看:当停止移动后,我们需要计算出现在停止在那么个模块上了,得到之后拿当前元素和它交换就好了。因为我们的所有模块大小都是相同的,因此就算出来还是比较简单的,大致就是先算出这个是属于哪一行哪一列的就好了,不过需要排除那些不在模块上的位置。

我们可以把这个计算同步到move事件上,就是移动的同时计算下面的模块,如有有就交换,这个比moveend稍微复杂一点,就是交换了之后要马上更新current。

自定义每行个数

现实中的模块大部分是一行占有几个的那种,这是就需要设置一个每行有几个模块:

在data中增加了num和speed配置,num表示一行有几个模块,这样的话,u_w的是这就没用了,因为它是动态计算出来的,计算过程如下:

计算过程也很简单,比如一个屏幕上等分的展现三个模块,那么每个模块宽度u_w=(allWidth - 4*s_h)/3,示意图如下:

background Layer 1 四个s_h 三个u_w

根据速度交换

之前的交换有个问题就是交换的太敏感,例如下图中1和6交换的换,很容易就触碰和旁边的2,3,4,5交换,这样就会越来越麻烦,本来只想换一个,现在换的越来越多。

background Layer 1 1 2 3 4 5 6

spped参数是用来检测用户的移动速度,它的计算逻辑是移动的时候,计算当前位置和上一次位置的距离:

如果移动的速度小于设定的,那么我们才会发生交换:

spped最小为1,如果设置为1,那么无论如何移动都不会交换,默认设置了1.5,表示如果速度比较快的时候,不会发生交换,如果速度比较慢,才会发生交换,这个也可以自己调整。

DEMO下载

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

其他文章

0
我要评论

评论

返回
×

我要评论

回复:

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

图片:

提交
还可以输入500个字