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

小程序拖拽排序 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信息,可以到那个元素的位置。

不过这里还是有一些问题需要注意,我们这里所有拖动的元素宽度和高度要是一样的,因为小程序不能直接操作视图层,所以如果我们拖动的元素宽度如果不同,我们就无法得到它的真实宽度。然后我们设置好一个宽度和高度之后,就先将他们绘制出来,大致如下:

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

关键绘制代码如下:

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

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

优化

有些人反应这个有点卡,因此优化了下,造成卡的主要原因是在移动的时候,大量的for循环整个数组进行修改,其实这个是没有必要的,现在额外增加了两个变量用来纪录当前的x和y,对于发生交换的情况我们只要交换那两个就好了,没有必要循环整个数组。

DEMO下载

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

其他文章

0
我要评论

评论

返回
×

我要评论

回复:

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

图片:

提交
还可以输入500个字