拖拽操作平时用的比较少,但是在最近的一个项目中用到了,踩了一些坑。本文作一简要总结。部分涉及G6的API,不影响理解大局。需求概览如下图所示。左边是GGEditor元素面板的React组件,右边是G6画布。现在您需要将元素从“元素面板”拖到“画布”中。要求:拖动时,蓝色虚线框与元素面板中对应的元素大小相同(矩形)。蓝色虚线框随鼠标移动,表示当前拖动位置元素面板上对应的元素应该不会改变??图中的黑色圆圈仅表示录屏软件的鼠标操作提示。拖拽方法总结与大多数只需要监听某个事件的DOM操作相比,原生拖拽功能的实现通常需要监听以下全部或部分事件:eventevent.target触发时机:dragisbeingdraggedby被拖动的元素(每隔几百毫秒触发一次)dragstart被拖动的元素刚刚开始拖动dragend被拖动的元素拖动结束(鼠标释放或esc)dragover被拖动的元素被拖动当到达某个目标时(每隔几百毫秒)dragenter当元素低于draggedelementisdraggedtoareleasableplacedragleavetheelementbelowthedraggedelementbelowdragawayfromatargetdroptheelementbelowthedraggedelement与dragend相同,在触发要实现的需求之前,首先要解释一些陷阱:左侧面板的元素不能设置为可拖动,因为原生拖拽自带阴影效果,如下图。显然这不是我们想要的。拖动时的蓝色虚线框应该是G6绘制的画布元素,因为画布可以放大或缩小,这个虚线框应该和实际放在画布上的元素一样大,而不是左边面板上的元素.(不了解G6的同学可以自行忽略)当拖动开始或鼠标放下时,创建一个与元素大小宽高相同,透明度为0的矩形shadowShape,并听其拖动和mouseup事件。收听文档上的dragenter事件。当目标为画布时,通过G6api创建蓝色虚线框dragShapeshadowShape。当shadowShape移动时,更新dragShape的位置。监听文档上的drop事件。当它落在画布上时,创建一个G6节点来完成整个过程。拖放以添加元素。??踩坑:需要防止dragover的默认行为,保证drop的正常触发。参考本问答总结1、GGEditor相比上一版本,实现了拖拽功能的延续性。以前,即使一直按住鼠标,一旦移出画布,拖动过程就终止了。GGEditor2上一版需要优化:由于蓝色虚线框是G6画布上的一个元素,它可以根据G6的缩放比例自动调整大小,所以不容易在G6画布上做出类似的虚线框在其他地方拖放的过程。间断感目前的代码在一个react组件中操作了很多native的事件监听,这对于React来说是不够的。考虑之后,直接开发一个新的组件,使用React的合成事件重写。
