为什么在放弃Html5拖拽Api之前用拖拽Api写了一个可拖拽组件?先来看看有赞做的类似拖拽式UI组件。它引用的sortablejs库封装了DragApi1。拖动时跟随鼠标的影子变成幽灵,由Api自动生成。但是因为这是一个很简单的页面,背景全是白色,拖的时候其实很难看清拖到哪里去了。虽然Api提供了e.dataTransfer.setDragImage(img,0,0)方法让我们改ghost,但是设置的img必须是HTMLimg元素,HTMLcanvas元素,否则必须是可见节点。简单的说,如果你设置的ghost不是canvas或者img元素,而是你自定义的html元素,那么你必须把它追加到文档中。document.getElementById("drag-with-create-add").addEventListener("dragstart",function(e){varcrt=this.cloneNode(true);crt.style.backgroundColor="red";document.body.appendChild(crt);e.dataTransfer.setDragImage(crt,0,0);},false);这个方法貌似解决了拖动不明显的问题,但是设置的ghost默认是有透明度的,你没有办法改变这个透明度。上图的页面,即使有一个cloneNode的元素跟着鼠标出来了,也因为这个原因感觉不清晰。2.快速拖动时,元素不断回流重绘。从上图我们可以看出,在拖动排序的时候,dom顺序是不断变化的。虽然拖动时页面已经加载完毕,但是开销并不大。会影响太大,但是如果能一拖就改变一次dom结构当然是最好的了。3.例子中的拖拽没有动画效果,鬼魂跟随给人的感觉就是拖拽很费力,有点吃力。这个问题不是吹毛求疵,后面可以在优化的可拖动组件动画中体现出来。使用鼠标事件拖放更流畅。优化后的拖动明显比例子顺畅很多,不会有拖拽的感觉。在拖动的过程中,无论怎么拖动,改变的只是元素的translate,并不会引起dom结构的变化,translate也不会引起回流和重绘,只是在之后进行了一次更新和排序拖放。在拖动过程中也可以清楚的看到当前被拖动的元素。影响文档流回流和重绘的css,请参考https://docs.google.com/sprea...优化思路是放弃html5的拖拽,使用鼠标事件mousedown,当当前点击的元素clone为ghost和original元素visibility:hidden;visibility让原来的元素仍然占据位置,这是拖动时不改变dom的关键。将ghost的位置设置为fixed,远离文档流,这样无论你怎么拖拽,都不会影响布局。给窗口加上mousemove和mouseend事件,这样不管鼠标怎么移动,鬼都会顺畅的跟着移动。mousemove时判断ghost等元素的位置,只用translate改变,直到真正拖拽结束才进行排序。优化的自定义重影让人们可以清楚地看到移动的元素。与vue一起使用的源码:https://github.com/sally2015/...,通过v-model轻松双向绑定数据列表
