可拖放交换位置的widget组件
拖放排序可被应用的地方非常多,像标签页的排序,widget组件的互换位置,或者任意摆放的图片墙等等。
从过程上考虑,首先要能把目标元素给拖动起来(⊙_⊙),之后检测与其他元素之间的距离执行交换,最后来释放掉目标元素。
如果是使用鼠标函数拖放的话,需要将可拖动的对象设定为绝对定位,这样能更方便的操作。因此基本上只要考虑以下几方面:
- 重绘位置
- 距离检测
- 序列重排
- 拖放函数
按照上面的步骤,先来个低配版的拖放排序
位置重绘
把获取到的元素位置由相对定位转换为绝对定位,同时把当前位置的left,top
值保存在position
变量中,方便后面元素交换时使用。
距离检测
距离检测的方式有很多种
一种是对鼠标坐标的监听,用当前坐标去遍历存储的元素坐标,使用left,top
和元素的width, height
判断鼠标是否在容器的范围内;
还有一种是把mousemove
事件绑定到可交换的元素上,当满足条件时触发交换。
先说一下后一种方法,在移动过程中发现后面的元素并不能触发前面元素的事件,比较之后看的出来应该是层级的原因,因此需要将被拖放的元素z-index
设置为负值。
|
|
序列重排
在上面设置了一个vacant
的变量,表示的是当前过程中哪一个位置是空闲的,所有的位置信息是在重绘的时候保存起来的,因此可以通过vacant
的值找到对应坐标,方便设置被交换元素以及被拖动元素的坐标。
问题
当然低配版的还是会存在一些瑕疵,问题多是由于动画效果持续时产生的,一种解决方法是拷贝一份被拖放元素并设置为透明隐藏,交换时使用透明元素,过渡效果使用可见元素。