拖放是一種很是流行的用戶界面模式。它的概念很簡單:點擊某個對象,並按住鼠標按鈕不放,將鼠標移到到另外一個區域,而後釋放按鈕將對象放到這裏。
拖放的基本概念很簡單:建立一個絕對定位的元素,使其能夠用鼠標移到。javascript
<body> <div style=""> <div class="draggable" style="width:100px;height:100px;position:absolute;background:red">移動的div</div> <div class="draggable" style="width:100px;height:100px;position:absolute;background:green;left:120px;">移動的div</div> </div> <script src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js"></script> <script src="http://apps.bdimg.com/libs/bootstrap/3.3.0/js/bootstrap.min.js"></script> <script type="text/javascript"> var DragDrop = function() { var dragging = null; var diffX = 0; var diffY = 0; function handleEvent(event) { event = event || window.event; var target = event.target; switch (event.type) { case "mousedown": if (target.className.indexOf("draggable") > -1) { dragging = target; diffX = event.clientX - target.offsetLeft; diffY = event.clientY - target.offsetTop; } break; case "mousemove": if (dragging !== null) { dragging.style.left = event.clientX - diffX + "px"; dragging.style.top = event.clientY - diffY + "px" } break; case "mouseup": dragging = null; break; } } //公共接口 return { enable: function() { document.addEventListener("mousedown", handleEvent, false); document.addEventListener("mousemove", handleEvent, false); document.addEventListener("mouseup", handleEvent, false); }, disable: function() { document.removeEventListener("mousedown", handleEvent, false); document.removeEventListener("mousemove", handleEvent, false); document.removeEventListener("mouseup", handleEvent, false) } } } DragDrop().enable(); </script> </body>
拖放功能還不能真正應用起來,除非能知道何時拖動開始了。從這點上看,前面的代碼沒有提供任何方法表示拖動開始、正在拖動或者已經結束。這時,能夠使用自定義事件來指示這幾個事件的發生,讓應用的其餘部分與拖動功能進行交互。css
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>拖放</title> <style type="text/css"> .drap-container { padding-top: 15px; } #dragWrap { height: 100px; background: #f2f2f2; width: 300px; height: 300px; border: 1px solid #ccc; position: relative; float: left; margin-right: 20px; padding: 10px; } .draggable { width: 100px; height: 100px; position: absolute; color: #fff; text-align: center; padding: 10px; cursor: pointer; } .box1 { background: #5972f1; } .box2 { left: 120px; background: #47bf6c; } #status { height: 35px; line-height: 35px; background: #fdf5f0; padding: 0 15px; border: 1px solid #fde4d4; margin-bottom: 10px; } @media(max-width:500px) { #dragWrap { width: 100%; float: none; } } </style> </head> <body class=""> <div class="container drap-container"> <div id="dragWrap"> <div class="draggable box1" id="box1">移動的div</div> <div class="draggable box2" id="box2">移動的div</div> </div> <div id="status">status</div> </div> <script type="text/javascript"> function EventTarget() { this.handlers = {} } EventTarget.prototype = { constructor: EventTarget, addHandler: function(type, handler) { console.log(type); //剛開始只有type並無爲this.handlers[type]賦值 if (typeof this.handlers[type] == "undefined") { this.handlers[type] = []; //console.log("hi") } //接着執行push this.handlers[type].push(handler); console.log(this.handlers[type]); }, fire: function(event) { if (!event.target) { event.target = this; //console.log("not have eventTarget") } if (this.handlers[event.type] instanceof Array) { //console.log("isArray") var handlers = this.handlers[event.type]; //循環執行多個事件 for (var i = 0, len = handlers.length; i < len; i++) { handlers[i](event); } } } } var DragDrop = function() { var wrap = document.getElementById("dragWrap"); var dragdrop = new EventTarget(); var dragging = null; var diffX = 0; var diffY = 0; var startEvt, moveEvt, endEvt; if ("ontouchstart" in window) { startEvt = "touchstart"; moveEvt = "touchmove"; endEvt = "touchend" } else { startEvt = "mousedown"; moveEvt = "mousemove"; endEvt = "mouseup"; } function handleEvent(event) { //獲取事件和對象 event = event || window.event; var target = event.target; //肯定事件類型 switch (event.type) { case startEvt: if (target.className.indexOf("draggable") > -1) { dragging = target; console.log(event.clientX) if (startEvt == "touchstart") { console.log(event) diffX = event.touches[0].clientX - target.offsetLeft; diffY = event.touches[0].clientY - target.offsetTop; dragdrop.fire({ type: "dragstart", target: dragging, x: event.touches[0].clientX, y: event.touches[0].clientY }); console.log(event.touches[0].clientX, event.touches[0].clientY) } else { diffX = event.clientX - target.offsetLeft; diffY = event.clientY - target.offsetTop; dragdrop.fire({ type: "dragstart", target: dragging, x: event.clientX, y: event.clientY }); } } break; case moveEvt: if (dragging !== null) { if (moveEvt == "touchmove") { event.preventDefault(); console.log(event) dragging.style.left = event.touches[0].clientX - diffX + "px"; dragging.style.top = event.touches[0].clientY - diffY + "px"; console.log(event.touches[0].clientX, event.touches[0].clientY) dragdrop.fire({ type: "drag", target: dragging, x: event.touches[0].clientX, y: event.touches[0].clientY }) } else { 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 endEvt: if (endEvt == "touchend") { console.log(endEvt) console.log(event) dragdrop.fire({ type: "dragend", target: dragging, x: event.changedTouches[0].clientX, y: event.changedTouches[0].clientY }) } else { dragdrop.fire({ type: "dragend", target: dragging, x: event.clientX, y: event.clientY }) } dragging = null; break; } } //公共接口 dragdrop.enable = function() { wrap.addEventListener(startEvt, handleEvent, false); wrap.addEventListener(moveEvt, handleEvent, false); wrap.addEventListener(endEvt, handleEvent, false); }, dragdrop.disable = function() { wrap.removeEventListener(startEvt, handleEvent, false); wrap.removeEventListener(moveEvt, handleEvent, false); wrap.removeEventListener(endEvt, handleEvent, false) } return dragdrop }(); //能夠寫成 //DragDrop=DragDrop() //返回EventTarget{disable:ƒ (),enable:ƒ (),handlers:{drag:[f],dragend:[f],dragstart:[f]}} //console.log(DragDrop) DragDrop.enable(); 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 = "Dragged " + event.target.id + " to(" + event.x + "," + event.y + ")"; }); DragDrop.addHandler("dragend", function(event) { var status = document.getElementById("status"); status.innerHTML = "Dragged " + event.target.id + " at(" + event.x + "," + event.y + ")"; }); </script> </body> </html>
因爲DragDrop對象是一個使用了模塊模式的單例,因此須要進行一些更改來使用EventTarget類型。首先,建立一個新的EventTarget 對象,而後添加enable()和disable()方法,最後返回這個對象。html
查看拖放效果java