这是具体的拖放代码的HTML,里面依赖两个组件:EventUtil.js是兼容浏览器添加方法的库,EventTarget.js是一个发布-订阅者模式的对象库。
EventUtil.js:
var EventUtil = { addHandler: function (element, type, handler) { if (element.addEventListener) { element.addEventListener(type, handler, false); } else if (element.attachEvent) { element.attachEvent("on" + type, handler); } else { element["on" + type] = handler; } }, removeHandler: function (element, type, handler) { if (element.removeEventListener) { element.removeEventListener(type, handler, false); } else if (element.detachEvent) { element.detachEvent("on" + type, handler); } else { element["on" + type] = null; } }, getEvent: function (event) { return event ? event : window.event; }, getTarget: function (event) { return event.target || event.srcElement; }, };
EventTarget.js:
function EventTarget() { this.handlers = {}; } EventTarget.prototype = { constructor: EventTarget, addHandler: function (type, handler) { if (typeof this.handlers[type] == "undefined") { this.handlers[type] = []; } this.handlers[type].push(handler); }, fire: function (event) { if (!event.target) { event.target = this; } if (this.handlers[event.type] instanceof Array) { var handlers = this.handlers[event.type]; for (var i = 0, len = handlers.length; i < len; i++) { handlers[i](event); } } }, removeHandler: function (type, handler) { if (this.handlers[type] instanceof Array) { var handlers = this.handlers[type]; for (var i = 0, len = handlers.length; i < len; i++) { if (handlers[i] === handler) { break; } } handlers.splice(i, 1); } } };
以下是拖拽功能实现的全代码,功能性比较强大,支持在mousestart时候有回调,mousemove时候也有回调,mouseup时候trigger事件后执行之前的订阅回调。
<html> <body> <div class="draggable" id="myDiv"></div> <div id="status"></div> <style> #myDiv { position: absolute; width: 200px; height: 200px; left: 0; top: 0; background-color: red; } </style> </body> <script src="EventUtil.js"></script> <script src="EventTarget.js"></script> <script> //event:传入的是事件类型 // EventUtil.addHandler(document, "mousemove", function (event) { // var myDiv = document.getElementById("myDiv"); // myDiv.style.left = event.clientX + "px"; // myDiv.style.top = event.clientY + "px"; // }); var DragDrop = function () { var dragdrop = new EventTarget(), dragging = null, diffX = 0, diffY = 0; function handleEvent(event) { event = EventUtil.getEvent(event); var target = EventUtil.getTarget(event); //确定事件类型 switch (event.type) { //鼠标按下 case "mousedown": if (target.className.indexOf("draggable") > -1) { dragging = target; diffX = event.clientX - target.offsetLeft; diffY = event.clientY - target.offsetTop; dragdrop.fire({ type: 'dragstart', target: dragging, x: event.clientX, y: event.clientY }); } break; //鼠标划过 case "mousemove": if (dragging !== null) { dragging.style.left = (event.clientX - diffX) + "px"; dragging.style.top = (event.clientY - diffY) + "px"; dragdrop.fire({ type: "drag", target: dragging, x: event.clientX, y: event.clientY }); } break; //鼠标放开 case "mouseup": dragdrop.fire({ type: "dragend", target: dragging, x: event.clientX, y: event.clientY }); dragging = null; break; } } //公用接口 dragdrop.enable= function () { EventUtil.addHandler(document, "mousedown", handleEvent); EventUtil.addHandler(document, "mousemove", handleEvent); EventUtil.addHandler(document, "mouseup", handleEvent); }, dragdrop.disable = function () { EventUtil.removeHandler(document, "mousedown", handleEvent); EventUtil.removeHandler(document, "mousemove", handleEvent); EventUtil.removeHandler(document, "mouseup", handleEvent); } return dragdrop }() DragDrop.addHandler("dragstart",function(event){ var status = document.getElementById('status'); status.innerHTML = 'Started dragging '+event.target.id; }) DragDrop.addHandler("drag",function(event){ var status = document.getElementById('status'); status.innerHTML = `<br/>Dragged ${event.target.id} to ${event.x},${event.y}`; }) DragDrop.addHandler("dragend",function(event){ var status = document.getElementById('status'); status.innerHTML = `<br/>Drapped ${event.target.id} at ${event.x},${event.y}`; }) DragDrop.enable() </script> </html>
【完】
无论多么难懂的书,读的次数多了,自然就懂了。