元芳,你怎么看?
女老师果然是女老师,逻辑能力不行啊,你就直接说,光标移动多少距离,目标元素的左上角位置就移动多少,不就行了。为什么要去关心光标在目标元素的位置呢。。。
还有写的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,欢迎指正。