元芳,你怎么看?
女老師果然是女老師,邏輯能力不行啊,你就直接說,光標移動多少距離,目標元素的左上角位置就移動多少,不就行了。為什么要去關心光標在目標元素的位置呢。。。
還有寫的js代碼,重用性不高。
UtilJS.EventUtil.addEmulationalDnD?=?function(element){ ????????if(!element)//element是必須的參數 ????????????throw?new?ReferenceError("Calling?UtilJS.EventUtil.addEmulationalDnD()?without?element?argument."); ????????//通過給element添加一個hasDnD的屬性,解決同一個元素綁定多次拖拽事件的情況 ????????if(typeof?element.hasDnD?==?"undefined")?element.hasDnD?=?false; ????????if(element.hasDnD?==?true) ????????????return; ????????else ????????????element.hasDnD?=?true; ???????? ????????//處理“非絕對定位(position:absolute;)的元素添加拖拽事件”的情況 ????????element.style.position?=?"absolute"; ????????var?rect?=?element.getBoundingClientRect(); ????????if(!element.style.left)?element.style.left?=?rect.left?+?"px"; ????????if(!element.style.top)?element.style.top?=?rect.top?+?"px"; ????????var?startPos?=?{?x?:?0,?y?:?0,?};//記錄鼠標按下的起始位置 ????????var?leftTopPos?=?{?left?:?0,?top?:?0,?};//記錄每次拖拽目標元素的左上角坐標 ????????var?isPressed?=?false;//鼠標是否在目標元素上按下的標記 ????????//鼠標左鍵按下事件 ????????function?mousePressed(event){ ????????????event?=?UtilJS.EventUtil.getEvent(event); ????????????startPos.x?=?event.clientX; ????????????startPos.y?=?event.clientY; ????????????leftTopPos.left?=?parseInt(element.style.left.split("px")[0]); ????????????leftTopPos.top?=?parseInt(element.style.top.split("px")[0]); ????????????isPressed?=?true; ????????} ????????//當鼠標左鍵在目標元素上按下后,鼠標在文檔中移動的同時拖動目標元素 ????????function?mouseMovedAfterPressed(event){ ????????????if(!isPressed) ????????????????return; ????????????var?startDragDistance?=?4;//超過4個像素,則開始拖拽 ????????????var?xDis?=?event.clientX?-?startPos.x; ????????????var?yDis?=?event.clientY?-?startPos.y; ????????????if(Math.sqrt(xDis*xDis?+?yDis*yDis)?<=?startDragDistance)?return; ????????????event?=?UtilJS.EventUtil.getEvent(event); ????????????element.style.cursor?=?"move"; ????????????element.style.left?=?leftTopPos.left?+?xDis?+?"px"; ????????????element.style.top?=?leftTopPos.top?+?yDis?+?"px"; ????????} ????????//鼠標左鍵松開 ????????function?mouseReleasedOnElement(){ ????????????element.style.cursor?=?"default"; ????????????isPressed?=?false; ????????} ????????this.addBubblingHandler(element,?"mousedown",?mousePressed); ????????this.addBubblingHandler(element,?"mouseup",?mouseReleasedOnElement); ????????this.addBubblingHandler(document,?"mousemove",?mouseMovedAfterPressed); ????????return?[mousePressed,?mouseReleasedOnElement,?mouseMovedAfterPressed]; ????}; ????/*?為目標對象注銷拖放事件?*/ ????UtilJS.EventUtil.removeEmulationalDnD?=?function(element,?handlers){ ????????if(!element?||?!handlers?||?handlers.length!==3)?return; ????????this.removeBubblingHandler(element,?"mousedown",?handlers[0]); ????????this.removeBubblingHandler(element,?"mouseup",?handlers[1]); ????????this.removeBubblingHandler(document,?"mousemove",?handlers[2]); ????}
其中的addBubblingHandler和removeBubblingHandler是前面幾節講的跨瀏覽器兼容的注冊、注銷事件監聽器的函數。
addEmulationalDnD可以為任意元素添加拖拽事件。如果有什么bug,歡迎指正。
2016-04-17
上面的鼠標左鍵并沒有處理,可以自行添加之。