拖拽操做平時用的比較少,在最近的一個項目中使用到了,而且踩了一些坑,本文作一個簡單的總結。涉及部分G6的API,不會對理解全局產生干擾。
以下圖所示,左側爲GGEditor元素面板React組件,右側爲G6畫布,現須要將元素從「元素面板」中拖拽到「畫布」上。要求:html
⚠️圖中的黑色圓圈僅爲錄屏軟件指明鼠標操做提示html5
相較於大部分DOM操做只須要監聽某一種事件,原生拖拽功能的實現一般須要監聽所有或部分的下述事件:react
事件 | event.target | 觸發時機 |
---|---|---|
drag |
被拖動元素 | 拖拽中(每幾百毫秒觸發一次) |
dragstart |
被拖動元素 | 剛開始拖拽 |
dragend |
被拖動元素 | 拖拽結束(鼠標釋放或esc ) |
dragover |
被拖動元素下方元素 | 拖拽到某一目標上時(每幾百毫秒一次) |
dragenter |
被拖動元素下方元素 | 被拖動元素進入可釋放處時 |
dragleave |
被拖動元素下方元素 | 拖拽離開某一目標時 |
drop |
被拖動元素下方元素 | 同dragend 且在其以前觸發 |
實現以前,有幾個踩坑點先說明:canvas
draggable
,由於原生拖拽自帶陰影效果,以下圖。
很明顯這不是咱們要的效果。api
G6
繪製成一個canvas
的元素,由於畫布能夠放大或縮小,這個虛線框應和實際放在畫布上的元素尺寸相同而不是左側面板的元素尺寸相同。(不瞭解G6的同窗自行忽略)shadowShape
,並監聽其drag
,mouseup
事件。document
上監聽dragenter
事件,當target
爲畫布時,經過G6
api建立一個藍色虛線框dragShape
shadowShape
移動的時候,更新dragShape
的位置document
上監聽drop
事件,落在畫布時,建立一個G6
的節點從而完成整個拖拽添加元素的功能。
1 相較於上個版本的GGEditor,實現了拖拽功能的連續性。以前,鼠標即便保持按下,一旦移出畫布,就終止了本次的拖拽過程。less
上個版本的GGEditor優化
2 待優化點:spa
React
,考慮以後直接開發一個新的組件,使用React的合成事件來重寫。