近期做了一个图片拖拽的需求,真是耗费不少脑细胞啊,下面来分享一下我的经验:
一、jquery-ui中的sortable实现拖拽功能,详见http://www.css88.com/jquery-ui-api/sortable/,这个文档很全面细致,我就不做介绍啦,说一下我遇到的问题吧
优点:
1.拖拽时,可以展示一个占位符,且可以自己定义样式,通过placeholder就可以配置占位符的class名;
2.拖拽结束后,可以用$container.sortable('toArray')直接输出拖拽后的列表ID数组,无论是拖拽前还是拖拽后都可以用这个方法输出,可以免于自己整理数组的麻烦。
缺点:无法获取拖拽结束后元素在列表中的index值,因为拖拽前后,元素的index值是不变的,这个就比较坑了。即使在mousedown时手动获取拖拽前的index值,也无法获取拖拽后的值。
note:如果你不需要拖拽前后的index值,这个是一个不错的选择。
二、sortable.js,详见http://www.jb51.net/article/96446.htm,用法这里也不做详细介绍啦,大家看文档,同样说一下我遇到的问题
优点:
1.可以获取元素拖拽前后的index值,这个非常方便,很多东西都直接注入到event中啦
2.原生js实现的,不需要jq
缺点:
1.在火狐上会打开新的选项卡,这个可以通过forceFallBack设置为true,禁用原生H5的拖拽,使用它封装的函数。
2.假如你的交互是上传入口始终在图片列表后展示,那么在IE中会有一个bug,在拖拽过程中,会把上传入口当作一个可拖拽的元素,参与拖拽排序。这个时候,有两个解决方案,一个是和交互同学沟通,把上传入口放在下一行展示,但是这样的话视觉上感觉不太好。还有一种方案是,把上传入口定位在图片列表之后,通过计算left和top值,动态定位,使上传入口始终在列表之后。
note:
以上两个插件都有一个共同的问题,就是如果你在列表上同样绑定了点击事件,在火狐上拖拽结束,会触发这个点击事件。经过多方查找并结合实际,终于找到方法。
把你的点击事件绑定在列表元素上,而拖拽过程中,把列表元素下的图片禁止默认行为并阻止冒泡,即使用e.preventDefault();e.stopPropagation();拖拽结束后,再把这个禁止用off解除掉,这时,你会发现,拖拽结束后还是会触发click事件了。你会疑惑,明明我已经off掉了,为何没生效呢?那这个到底怎么off呢?
加一个定时器setTimeout,在300ms后再执行off。这时,你会发现事件不会出发click事件,并且click事件也可用了。
原因在于,鼠标的事件,click事件在mousedown,mouseup后触发,当你立即off时,这个就会触发click事件,所以我们需要有一个延迟,当事件流到click时,它还是被禁止的,这时就不会触发click了。延迟off,这样也可以保证列表的click事件正常可用。